sfztools / sfizz

SFZ parser and synth c++ library, providing a JACK standalone client
https://sfz.tools/sfizz/
BSD 2-Clause "Simplified" License
402 stars 58 forks source link

Crash with error message: "Assert failed: !voice->isInSisterRing()" #1180

Closed jonulrich closed 9 months ago

jonulrich commented 1 year ago

So far I've only run into this issue with several instruments with long sustains from the Versilian Community Sample Library. I can reproduce it fairly reliably by holding the sustain pedal, quickly arppegiating over 6-8 notes 3 or 4 times and then releasing the sustain pedal. the cli output from sfizz_jack reads as follows:

Flags
- Client name: sfizz
- Oversampling: 1x
- Preloaded size: 8192
- Num of voices: 32
- Audio Autoconnect: 1
- Verbose State: 0
Positional arguments: Grand Piano, Kawai.sfz,
Instrument loaded: Grand Piano, Kawai.sfz
===========================
Total:
        Masters: 0
        Groups: 3
        Regions: 222
        Curves: 7
        PreloadedSamples: 222
===========================
Unknown opcodes:

> Assert failed: !voice->isInSisterRing()
Assert failed at /usr/src/debug/sfizz/sfizz-1.2.1/src/sfizz/SisterVoiceRing.h:139
zsh: trace trap (core dumped)  sfizz_jack Grand\ Piano,\ Kawai.sfz --jack_autoconnect true
paulfd commented 1 year ago

I'll try to investigate. Probably something to do with voice stealing since you have a relatively low number of voices.

iv-m commented 1 year ago

I'm having the same issue with sfizz 1.2.2, both LV2 plugins (build with PSA) and sfizz_jack.

The fastest way to reproduce it is to play several notes with sustain, then release the sustain. At the moment sustain is released, sifzz crashes.

iv-m commented 1 year ago

From LV2 plugin loaded to ardour 7, I managed to get a decent backtrace with gdb:

(gdb) bt
#0  sfz::SisterVoiceRingBuilder::addVoiceToRing (voice=0x55555dbf12b0, this=0x7fff953f8a78) at /usr/src/debug/sfizz-ui/library/src/sfizz/SisterVoiceRing.h:141
#1  sfz::Synth::Impl::startVoice (this=<optimized out>, layer=<optimized out>, delay=<optimized out>, triggerEvent=..., ring=...)
    at /usr/src/debug/sfizz-ui/library/src/sfizz/Synth.cpp:1314
#2  0x00007fff4a4ea254 in sfz::Synth::Impl::startDelayedSustainReleases (ring=..., delay=<optimized out>, layer=0x55555c95d4c0, this=<optimized out>)
    at /usr/src/debug/sfizz-ui/library/src/sfizz/Synth.cpp:1400
#3  sfz::Synth::Impl::ccDispatch (value=0, ccNumber=<optimized out>, delay=225, this=0x55555db41ff0) at /usr/src/debug/sfizz-ui/library/src/sfizz/Synth.cpp:1437
#4  sfz::Synth::Impl::performHdcc(int, int, float, bool) [clone .constprop.0] (this=0x55555db41ff0, delay=225, ccNumber=<optimized out>, normValue=0, asMidi=false)
    at /usr/src/debug/sfizz-ui/library/src/sfizz/Synth.cpp:1497
#5  0x00007fff4a41cec2 in sfizz_automate_hdcc (norm_value=<optimized out>, cc_number=64, delay=225, synth=<optimized out>)
    at /usr/src/debug/sfizz-ui/library/src/sfizz/sfizz_wrapper.cpp:143
#6  sfizz_lv2_process_midi_event (ev=0x7fff7001e5cc, self=<optimized out>) at /usr/src/debug/sfizz-ui/plugins/lv2/sfizz.cpp:898
#7  run (instance=0x55555d94b540, sample_count=256) at /usr/src/debug/sfizz-ui/plugins/lv2/sfizz.cpp:1190
iv-m commented 1 year ago

Looking at Synth::Impl::startVoice and Voice::startVoice, I don't see anything that removes the selected voice from sister ring if it already was in one. It looks like one of those startVoice method should call Voice::reset, but I'm not sure which one.

iv-m commented 1 year ago

Adding a call to selectedVoice->reset() right before this line

https://github.com/sfztools/sfizz/blob/1.2.2/src/sfizz/Synth.cpp#L1313

fixed the problem for me.

paulfd commented 11 months ago

This seems like a reasonable thing to add, thanks for looking into it!