Added proper support for off_modes

This commit is contained in:
Paul Ferrand 2019-12-21 21:24:49 +01:00
parent ed7d5369a7
commit 92aaa2a17e
6 changed files with 45 additions and 9 deletions

View file

@ -224,10 +224,13 @@ int ADSREnvelope<Type>::getRemainingDelay() const noexcept
}
template <class Type>
void ADSREnvelope<Type>::startRelease(int releaseDelay) noexcept
void ADSREnvelope<Type>::startRelease(int releaseDelay, bool fastRelease) noexcept
{
shouldRelease = true;
this->releaseDelay = releaseDelay;
if (fastRelease)
this->release = 0;
}
}

View file

@ -66,8 +66,11 @@ public:
* @brief Start the envelope release after a delay.
*
* @param releaseDelay the delay before releasing in samples
* @param fastRelease whether the release should be fast (i.e. 0 or so) or
* follow the release duration that was set when
* initializing the envelope
*/
void startRelease(int releaseDelay) noexcept;
void startRelease(int releaseDelay, bool fastRelease = false) noexcept;
/**
* @brief Is the envelope smoothing?
*

View file

@ -130,7 +130,7 @@ bool sfz::Voice::isFree() const noexcept
return (state == State::idle);
}
void sfz::Voice::release(int delay) noexcept
void sfz::Voice::release(int delay, bool fastRelease) noexcept
{
if (state != State::playing)
return;
@ -139,7 +139,7 @@ void sfz::Voice::release(int delay) noexcept
reset();
} else {
state = State::release;
egEnvelope.startRelease(delay);
egEnvelope.startRelease(delay, fastRelease);
}
}
@ -499,8 +499,11 @@ void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
bool sfz::Voice::checkOffGroup(int delay, uint32_t group) noexcept
{
if (region != nullptr && triggerType == TriggerType::NoteOn && region->offBy && *region->offBy == group) {
release(delay);
if (region == nullptr)
return false;
if (triggerType == TriggerType::NoteOn && region->offBy && *region->offBy == group) {
release(delay, region->offMode == SfzOffMode::fast);
return true;
}

View file

@ -264,8 +264,9 @@ private:
* @brief Release the voice after a given delay
*
* @param delay
* @param fastRelease whether to do a normal release or cut the voice abruptly
*/
void release(int delay) noexcept;
void release(int delay, bool fastRelease = false) noexcept;
Region* region { nullptr };
enum class State {

View file

@ -355,7 +355,6 @@ TEST_CASE("[Files] Default path is ignored for generators")
REQUIRE(synth.getRegionView(0)->sample == R"(*sine)");
}
TEST_CASE("[Files] Set CC applies properly to all channels")
{
sfz::Synth synth;
@ -366,7 +365,6 @@ TEST_CASE("[Files] Set CC applies properly to all channels")
}
}
TEST_CASE("[Files] Note and octave offsets")
{
sfz::Synth synth;
@ -408,3 +406,28 @@ TEST_CASE("[Files] Note and octave offsets")
REQUIRE( synth.getRegionView(6)->pitchKeycenter == 50 );
}
TEST_CASE("[Files] Off modes")
{
sfz::Synth synth;
synth.setSamplesPerBlock(256);
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/off_mode.sfz");
REQUIRE( synth.getNumRegions() == 3 );
synth.noteOn(0, 0, 64, 63);
REQUIRE( synth.getNumActiveVoices() == 2 );
const auto* fastVoice =
synth.getVoiceView(0)->getRegion()->offMode == SfzOffMode::fast ?
synth.getVoiceView(0) :
synth.getVoiceView(1) ;
const auto* normalVoice =
synth.getVoiceView(0)->getRegion()->offMode == SfzOffMode::fast ?
synth.getVoiceView(1) :
synth.getVoiceView(0) ;
synth.noteOn(100, 0, 63, 63);
REQUIRE( synth.getNumActiveVoices() == 3 );
sfz::AudioBuffer<float> buffer { 2, 256 };
synth.renderBlock(buffer);
REQUIRE( synth.getNumActiveVoices() == 2 );
REQUIRE( fastVoice->isFree() );
REQUIRE( !normalVoice->isFree() );
}

View file

@ -0,0 +1,3 @@
<region> group=1 off_by=2 key=64 off_mode=fast ampeg_release=0.1 sample=mono_sample.wav
<region> group=1 off_by=2 key=64 off_mode=normal ampeg_release=0.1 sample=mono_sample.wav
<region> group=2 key=63 off_mode=normal ampeg_release=0.1 sample=mono_sample.wav