Skip to content

Commit 4055582

Browse files
KKQ-KKQpaulfd
authored andcommitted
Fixes an issue that caused stuck notes.
Fixes an issue that caused a crash when using a loop.
1 parent 4cafa37 commit 4055582

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

src/sfizz/ADSREnvelope.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ void ADSREnvelope::getBlockInternal(absl::Span<Float> output) noexcept
101101
if (releaseDelay > 0) {
102102
// prevent computing the segment further than release point
103103
size = std::min<size_t>(size, releaseDelay);
104-
} else if (releaseDelay == 0 && delay < 0) {
104+
} else if (releaseDelay == 0 && delay <= 0) {
105105
// release takes effect this frame
106106
currentState = State::Release;
107107
releaseDelay = -1;

src/sfizz/Voice.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,7 @@ void Voice::Impl::fillWithData(AudioSpan<float> buffer) noexcept
11881188
unsigned i = 0;
11891189
while (i < numSamples) {
11901190
int wrappedIndex = (*indices)[i] - loop.size * blockRestarts;
1191-
if (wrappedIndex > loop.end) {
1191+
while (wrappedIndex > loop.end) {
11921192
wrappedIndex -= loop.size;
11931193
blockRestarts += 1;
11941194
loop_.restarts += 1;

tests/SynthT.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -2160,3 +2160,46 @@ TEST_CASE("[Synth] Reuse offed voices in the last case scenario for new notes")
21602160
REQUIRE( notes == std::vector<int> { i - 1, i } );
21612161
}
21622162
}
2163+
2164+
TEST_CASE("[Synth] Note on and off at the maximum delay")
2165+
{
2166+
sfz::Synth synth;
2167+
synth.setSampleRate(12800);
2168+
synth.setSamplesPerBlock(128);
2169+
sfz::AudioBuffer<float> buffer { 2, static_cast<unsigned>(synth.getSamplesPerBlock()) };
2170+
synth.loadSfzString(fs::current_path() / "tests/TestFiles/noteonoff.sfz", R"(
2171+
<region> loop_start=4 loop_end=124 ampeg_release=0.5 sample=looped_flute.wav
2172+
)");
2173+
synth.setNumVoices(128);
2174+
synth.noteOn(127, 64, 64);
2175+
CHECK(synth.getNumActiveVoices() == 1);
2176+
synth.noteOff(127, 64, 0);
2177+
CHECK(synth.getNumActiveVoices() == 1);
2178+
// Render for a while
2179+
for (int i = 0; i < 100; ++i)
2180+
synth.renderBlock(buffer);
2181+
CHECK(synth.getNumActiveVoices() == 0);
2182+
}
2183+
2184+
TEST_CASE("[Synth] Note on and off with delay")
2185+
{
2186+
sfz::Synth synth;
2187+
synth.setSampleRate(12800);
2188+
synth.setSamplesPerBlock(128);
2189+
sfz::AudioBuffer<float> buffer { 2, static_cast<unsigned>(synth.getSamplesPerBlock()) };
2190+
synth.loadSfzString(fs::current_path() / "tests/TestFiles/noteonoff.sfz", R"(
2191+
<region> loop_start=4 loop_end=124 ampeg_release=0.5 sample=looped_flute.wav
2192+
)");
2193+
synth.setNumVoices(128);
2194+
2195+
int i;
2196+
for (i = 0; i < 127; ++i) {
2197+
synth.noteOn(i, i, 64);
2198+
synth.noteOff(i+1, i, 0);
2199+
}
2200+
CHECK(synth.getNumActiveVoices() == 127);
2201+
// Render for a while
2202+
for (int i = 0; i < 100; ++i)
2203+
synth.renderBlock(buffer);
2204+
CHECK(synth.getNumActiveVoices() == 0);
2205+
}

0 commit comments

Comments
 (0)