diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index b940031a..2d96835a 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -349,11 +349,9 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) break; case hash("release"): trigger = SfzTrigger::release; - loopMode = SfzLoopMode::one_shot; break; case hash("release_key"): trigger = SfzTrigger::release_key; - loopMode = SfzLoopMode::one_shot; break; default: DBG("Unknown trigger mode: " << opcode.value); diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 0ce7d527..5a0b6103 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -507,6 +507,9 @@ void sfz::Synth::finalizeSfzLoad() region->loopMode = SfzLoopMode::loop_continuous; } + if (region->isRelease() && !region->loopMode) + region->loopMode = SfzLoopMode::one_shot; + if (region->loopRange.getEnd() == Default::loopRange.getEnd()) region->loopRange.setEnd(region->sampleEnd); diff --git a/tests/FilesT.cpp b/tests/FilesT.cpp index f92f496c..6c0c6507 100644 --- a/tests/FilesT.cpp +++ b/tests/FilesT.cpp @@ -575,6 +575,28 @@ TEST_CASE("[Files] Looped regions can start at 0") REQUIRE( synth.getRegionView(0)->loopRange == Range { 0, synth.getRegionView(0)->sampleEnd } ); } +TEST_CASE("[Synth] Release triggers automatically sets the loop mode") +{ + sfz::Synth synth; + synth.loadSfzString(fs::current_path() / "tests/TestFiles/triggers_setting_loops.sfz", R"( + sample=kick.wav pitch_keycenter=69 loop_mode=loop_sustain trigger=release + sample=kick.wav pitch_keycenter=69 loop_mode=loop_sustain trigger=release_key + sample=kick.wav pitch_keycenter=69 trigger=release loop_mode=loop_sustain + sample=kick.wav pitch_keycenter=69 trigger=release_key loop_mode=loop_sustain + sample=looped_flute.wav pitch_keycenter=69 trigger=release_key + sample=kick.wav pitch_keycenter=69 trigger=release_key // These are normal and set to one_shot + sample=kick.wav pitch_keycenter=69 trigger=release + )"); + REQUIRE( synth.getNumRegions() == 7 ); + REQUIRE( synth.getRegionView(0)->loopMode == SfzLoopMode::loop_sustain ); + REQUIRE( synth.getRegionView(1)->loopMode == SfzLoopMode::loop_sustain ); + REQUIRE( synth.getRegionView(2)->loopMode == SfzLoopMode::loop_sustain ); + REQUIRE( synth.getRegionView(3)->loopMode == SfzLoopMode::loop_sustain ); + REQUIRE( synth.getRegionView(4)->loopMode == SfzLoopMode::loop_continuous ); + REQUIRE( synth.getRegionView(5)->loopMode == SfzLoopMode::one_shot ); + REQUIRE( synth.getRegionView(6)->loopMode == SfzLoopMode::one_shot ); +} + TEST_CASE("[Files] Case sentitiveness") { const fs::path sfzFilePath = fs::current_path() / "tests/TestFiles/case_insensitive.sfz"; diff --git a/tests/RegionT.cpp b/tests/RegionT.cpp index cdf7a13c..9e90b7db 100644 --- a/tests/RegionT.cpp +++ b/tests/RegionT.cpp @@ -497,15 +497,12 @@ TEST_CASE("[Region] Parsing opcodes") REQUIRE(region.trigger == SfzTrigger::attack); region.parseOpcode({ "trigger", "release" }); REQUIRE(region.trigger == SfzTrigger::release); - REQUIRE(region.loopMode == SfzLoopMode::one_shot); + region.parseOpcode({ "trigger", "release_key" }); + REQUIRE(region.trigger == SfzTrigger::release_key); region.parseOpcode({ "trigger", "first" }); REQUIRE(region.trigger == SfzTrigger::first); region.parseOpcode({ "trigger", "legato" }); REQUIRE(region.trigger == SfzTrigger::legato); - region.parseOpcode({ "loop_mode", "no_loop" }); - region.parseOpcode({ "trigger", "release_key" }); - REQUIRE(region.trigger == SfzTrigger::release_key); - REQUIRE(region.loopMode == SfzLoopMode::one_shot); } SECTION("on_locc, on_hicc")