From 5e40e31c83a86a91a670f0da4ad1ed690b520326 Mon Sep 17 00:00:00 2001 From: Paul Fd Date: Sun, 15 Mar 2020 10:56:22 +0100 Subject: [PATCH 1/7] Only set the sample rate, per block, and the worker in setEnable; don't recreate the synth --- vst/SfizzVstProcessor.cpp | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/vst/SfizzVstProcessor.cpp b/vst/SfizzVstProcessor.cpp index 62d6b785..ea87680f 100644 --- a/vst/SfizzVstProcessor.cpp +++ b/vst/SfizzVstProcessor.cpp @@ -46,6 +46,13 @@ tresult PLUGIN_API SfizzVstProcessor::initialize(FUnknown* context) _state = SfizzVstState(); + fprintf(stderr, "[sfizz] new synth\n"); + _synth.reset(new sfz::Sfizz); + if (!_synth) { + fprintf(stderr, "[sfizz] Could not create synth!\n"); + return kResultFalse; + } + return result; } @@ -105,21 +112,27 @@ tresult PLUGIN_API SfizzVstProcessor::canProcessSampleSize(int32 symbolicSampleS tresult PLUGIN_API SfizzVstProcessor::setActive(TBool state) { - stopBackgroundWork(); - _synth.reset(); + sfz::Sfizz* synth = _synth.get(); + + if (!synth) { + fprintf(stderr, "[sfizz] Synth was destroyed? Trying to recreate...\n"); + synth = new sfz::Sfizz; + if (!synth) { + fprintf(stderr, "[sfizz] Something is very wrong\n"); + return kResultFalse; + } + _synth.reset(synth); + syncStateToSynth(); + } if (state) { - fprintf(stderr, "[Sfizz] new synth\n"); - sfz::Sfizz* synth = new sfz::Sfizz; - _synth.reset(synth); - - synth->setSampleRate(processSetup.sampleRate); - synth->setSamplesPerBlock(processSetup.maxSamplesPerBlock); - - syncStateToSynth(); + _synth->setSampleRate(processSetup.sampleRate); + _synth->setSamplesPerBlock(processSetup.maxSamplesPerBlock); _workRunning = true; _worker = std::thread([this]() { doBackgroundWork(); }); + } else { + stopBackgroundWork(); } return kResultTrue; From ac93e0cbd38ba27bd42debcc710496c645498d53 Mon Sep 17 00:00:00 2001 From: Paul Fd Date: Sun, 15 Mar 2020 14:04:22 +0100 Subject: [PATCH 2/7] Remove the synth recreations --- vst/SfizzVstProcessor.cpp | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/vst/SfizzVstProcessor.cpp b/vst/SfizzVstProcessor.cpp index ea87680f..cc86e65e 100644 --- a/vst/SfizzVstProcessor.cpp +++ b/vst/SfizzVstProcessor.cpp @@ -48,10 +48,6 @@ tresult PLUGIN_API SfizzVstProcessor::initialize(FUnknown* context) fprintf(stderr, "[sfizz] new synth\n"); _synth.reset(new sfz::Sfizz); - if (!_synth) { - fprintf(stderr, "[sfizz] Could not create synth!\n"); - return kResultFalse; - } return result; } @@ -114,16 +110,8 @@ tresult PLUGIN_API SfizzVstProcessor::setActive(TBool state) { sfz::Sfizz* synth = _synth.get(); - if (!synth) { - fprintf(stderr, "[sfizz] Synth was destroyed? Trying to recreate...\n"); - synth = new sfz::Sfizz; - if (!synth) { - fprintf(stderr, "[sfizz] Something is very wrong\n"); - return kResultFalse; - } - _synth.reset(synth); - syncStateToSynth(); - } + if (!synth) + return kResultFalse; if (state) { _synth->setSampleRate(processSetup.sampleRate); From 7d625bc736fa88bab0ed8a90b867e37f2398a1fa Mon Sep 17 00:00:00 2001 From: Paul Fd Date: Sun, 15 Mar 2020 23:16:40 +0100 Subject: [PATCH 3/7] Add a panic button --- src/sfizz.h | 7 +++++++ src/sfizz.hpp | 5 +++++ src/sfizz/Synth.cpp | 12 ++++++++++++ src/sfizz/Synth.h | 6 ++++++ src/sfizz/sfizz.cpp | 5 +++++ src/sfizz/sfizz_wrapper.cpp | 7 +++++++ tests/SynthT.cpp | 11 +++++++++++ 7 files changed, 53 insertions(+) diff --git a/src/sfizz.h b/src/sfizz.h index c9da6d85..4063d498 100644 --- a/src/sfizz.h +++ b/src/sfizz.h @@ -369,6 +369,13 @@ SFIZZ_EXPORTED_API void sfizz_enable_logging(sfizz_synth_t* synth); */ SFIZZ_EXPORTED_API void sfizz_disable_logging(sfizz_synth_t* synth); +/** + * @brief Shuts down the current processing, clear buffers and reset the voices. + * + * @param synth + */ +SFIZZ_EXPORTED_API void sfizz_all_sound_off(sfizz_synth_t* synth); + #ifdef __cplusplus } #endif diff --git a/src/sfizz.hpp b/src/sfizz.hpp index be2785b3..199729bf 100644 --- a/src/sfizz.hpp +++ b/src/sfizz.hpp @@ -256,6 +256,11 @@ public: * */ void disableLogging() noexcept; + /** + * @brief Shuts down the current processing, clear buffers and reset the voices. + * + */ + void allSoundOff() noexcept; private: std::unique_ptr synth; }; diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 8f7612ef..4c4bce96 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -579,6 +579,8 @@ void sfz::Synth::noteOn(int delay, int noteNumber, uint8_t velocity) noexcept ASSERT(noteNumber < 128); ASSERT(noteNumber >= 0); + DBG("Note on at " << noteNumber << " (" << +velocity << ")"); + ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration }; resources.midiState.noteOnEvent(delay, noteNumber, velocity); @@ -595,6 +597,8 @@ void sfz::Synth::noteOff(int delay, int noteNumber, uint8_t velocity) noexcept ASSERT(noteNumber >= 0); UNUSED(velocity); + DBG("Note off at " << noteNumber << " (" << +velocity << ")"); + ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration }; resources.midiState.noteOffEvent(delay, noteNumber, velocity); @@ -962,3 +966,11 @@ void sfz::Synth::disableLogging() noexcept { resources.logger.disableLogging(); } + +void sfz::Synth::allSoundOff() noexcept +{ + for (auto &voice: voices) + voice->reset(); + for (auto& effectBus: effectBuses) + effectBus->clear(); +} diff --git a/src/sfizz/Synth.h b/src/sfizz/Synth.h index 41a56c53..2fb1eb16 100644 --- a/src/sfizz/Synth.h +++ b/src/sfizz/Synth.h @@ -361,6 +361,12 @@ public: * */ void disableLogging() noexcept; + + /** + * @brief Shuts down the current processing, clear buffers and reset the voices. + * + */ + void allSoundOff() noexcept; protected: /** * @brief The parser callback; this is called by the parent object each time diff --git a/src/sfizz/sfizz.cpp b/src/sfizz/sfizz.cpp index 61e5a0c5..ee4ef4f1 100644 --- a/src/sfizz/sfizz.cpp +++ b/src/sfizz/sfizz.cpp @@ -195,3 +195,8 @@ void sfz::Sfizz::disableLogging() noexcept { synth->disableLogging(); } + +void sfz::Sfizz::allSoundOff() noexcept +{ + synth->allSoundOff(); +} diff --git a/src/sfizz/sfizz_wrapper.cpp b/src/sfizz/sfizz_wrapper.cpp index 32ab355a..7e18d2f6 100644 --- a/src/sfizz/sfizz_wrapper.cpp +++ b/src/sfizz/sfizz_wrapper.cpp @@ -237,12 +237,19 @@ void sfizz_enable_logging(sfizz_synth_t* synth) auto self = reinterpret_cast(synth); return self->enableLogging(); } + void sfizz_disable_logging(sfizz_synth_t* synth) { auto self = reinterpret_cast(synth); return self->disableLogging(); } +void sfizz_all_sound_off(sfizz_synth_t* synth) +{ + auto self = reinterpret_cast(synth); + return self->allSoundOff(); +} + #ifdef __cplusplus } #endif diff --git a/tests/SynthT.cpp b/tests/SynthT.cpp index 9ed0c73c..70806b5e 100644 --- a/tests/SynthT.cpp +++ b/tests/SynthT.cpp @@ -26,6 +26,17 @@ TEST_CASE("[Synth] Play and check active voices") REQUIRE(synth.getNumActiveVoices() == 0); } +TEST_CASE("[Synth] All sound off") +{ + sfz::Synth synth; + synth.loadSfzFile(fs::current_path() / "tests/TestFiles/groups_avl.sfz"); + synth.noteOn(0, 36, 24); + synth.noteOn(0, 36, 89); + REQUIRE(synth.getNumActiveVoices() == 2); + synth.allSoundOff(); + REQUIRE(synth.getNumActiveVoices() == 0); +} + TEST_CASE("[Synth] Change the number of voice while playing") { sfz::Synth synth; From 98392a7b9a2d2714226680a7e2ed476c67a30737 Mon Sep 17 00:00:00 2001 From: Paul Fd Date: Sun, 15 Mar 2020 23:24:07 +0100 Subject: [PATCH 4/7] Add the panic to the VST processor --- vst/SfizzVstProcessor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vst/SfizzVstProcessor.cpp b/vst/SfizzVstProcessor.cpp index cc86e65e..97795c41 100644 --- a/vst/SfizzVstProcessor.cpp +++ b/vst/SfizzVstProcessor.cpp @@ -114,12 +114,13 @@ tresult PLUGIN_API SfizzVstProcessor::setActive(TBool state) return kResultFalse; if (state) { - _synth->setSampleRate(processSetup.sampleRate); - _synth->setSamplesPerBlock(processSetup.maxSamplesPerBlock); + synth->setSampleRate(processSetup.sampleRate); + synth->setSamplesPerBlock(processSetup.maxSamplesPerBlock); _workRunning = true; _worker = std::thread([this]() { doBackgroundWork(); }); } else { + synth->allSoundOff(); stopBackgroundWork(); } From 55a816f703bf15022fb8860cf206f6612bb6d9a1 Mon Sep 17 00:00:00 2001 From: Paul Fd Date: Sun, 15 Mar 2020 23:24:15 +0100 Subject: [PATCH 5/7] Remove the debug messages --- src/sfizz/Synth.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 4c4bce96..4c692168 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -579,8 +579,6 @@ void sfz::Synth::noteOn(int delay, int noteNumber, uint8_t velocity) noexcept ASSERT(noteNumber < 128); ASSERT(noteNumber >= 0); - DBG("Note on at " << noteNumber << " (" << +velocity << ")"); - ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration }; resources.midiState.noteOnEvent(delay, noteNumber, velocity); @@ -597,8 +595,6 @@ void sfz::Synth::noteOff(int delay, int noteNumber, uint8_t velocity) noexcept ASSERT(noteNumber >= 0); UNUSED(velocity); - DBG("Note off at " << noteNumber << " (" << +velocity << ")"); - ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration }; resources.midiState.noteOffEvent(delay, noteNumber, velocity); From e068ec77e59bd9c5c1172558c17671a9a46daf9c Mon Sep 17 00:00:00 2001 From: Paul Fd Date: Sun, 15 Mar 2020 23:25:25 +0100 Subject: [PATCH 6/7] Add the panic to the LV2 for good measure --- lv2/sfizz.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lv2/sfizz.c b/lv2/sfizz.c index 0b2f6402..b0b9ab5d 100644 --- a/lv2/sfizz.c +++ b/lv2/sfizz.c @@ -416,7 +416,8 @@ activate(LV2_Handle instance) static void deactivate(LV2_Handle instance) { - UNUSED(instance); + sfizz_plugin_t *self = (sfizz_plugin_t *)instance; + sfizz_all_sound_off(self->synth); } static void From 4d3ea7da304814c3111b9656c2af620c438ed42d Mon Sep 17 00:00:00 2001 From: Paul Fd Date: Mon, 16 Mar 2020 00:32:31 +0100 Subject: [PATCH 7/7] Disable the callback before killing the voices --- src/sfizz/Synth.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 4c692168..56c5126c 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -965,6 +965,11 @@ void sfz::Synth::disableLogging() noexcept void sfz::Synth::allSoundOff() noexcept { + AtomicDisabler callbackDisabler{ canEnterCallback }; + while (inCallback) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + for (auto &voice: voices) voice->reset(); for (auto& effectBus: effectBuses)