From 87ee3dae56a0603e145d2284b1754f4208203fa7 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 11 Sep 2023 07:56:46 -0400 Subject: [PATCH 1/3] Set up the VST3 Root Until so vst3 validator succeeds (#128) Set up all the IDs required to get a valid root unit in the steinberg validator. Addresses #118 --- src/wrapasvst3.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/wrapasvst3.cpp b/src/wrapasvst3.cpp index 2e081662..7a2e011d 100644 --- a/src/wrapasvst3.cpp +++ b/src/wrapasvst3.cpp @@ -461,7 +461,6 @@ Vst::UnitID ClapAsVst3::getOrCreateUnitInfo(const char* modulename) } else { - // the unit needs to be created Steinberg::Vst::String128 name; std::string u8name(path[i]); if (VST3::StringConvert::convert(u8name, name)) @@ -581,10 +580,14 @@ void ClapAsVst3::setupParameters(const clap_plugin_t* plugin, const clap_plugin_ units.clear(); { - Vst::String128 rootname(STR16("root")); - Vst::Unit* newunit = new Vst::Unit(rootname, Vst::kNoParentUnitId, - Vst::kRootUnitId); // a new unit without a program list - addUnit(newunit); + Vst::UnitInfo rootInfo; + rootInfo.id = Vst::kRootUnitId; + rootInfo.parentUnitId = Vst::kNoParentUnitId; + rootInfo.programListId = Vst::kNoProgramListId; + VST3::StringConvert::convert(std::string("Root"), rootInfo.name); + + auto rootUnit = new Vst::Unit(rootInfo); + addUnit(rootUnit); } auto numparams = params->count(plugin); From c960f304eaabd74e5a992454813886a45b9f53be Mon Sep 17 00:00:00 2001 From: defiantnerd <97224712+defiantnerd@users.noreply.github.com> Date: Mon, 11 Sep 2023 14:29:24 +0200 Subject: [PATCH 2/3] defensive countermeasure to bug in Renoise (#126) * defensive countermeasure to bug in Renoise * set state off at destruction * added an explanation for State class --- src/detail/vst3/os/osutil.h | 44 ++++++++++++++++++++++++++++++++++++- src/wrapasvst3.cpp | 6 +++-- src/wrapasvst3.h | 2 ++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/detail/vst3/os/osutil.h b/src/detail/vst3/os/osutil.h index c1d2572b..30d9dea0 100644 --- a/src/detail/vst3/os/osutil.h +++ b/src/detail/vst3/os/osutil.h @@ -7,12 +7,54 @@ #include #include +#include #define FMT_HEADER_ONLY 1 #include "fmt/format.h" #include "fmt/ranges.h" namespace os { + +class State +{ + // the State class ensures that a specific function pair (like init/terminate) is only called in pairs. + // the bool _state reflects if the _on lambda has already been called + // on destruction, it makes sure that the _off lambda is definitely called. + // + // the construct should only be applied to when no state machine can cover this properly + // or your own code depends on correct calling sequences of an external code base and should + // help to implement defensive programming. + + public: + State(std::function on, std::function off) : _on(on), _off(off) + { + } + ~State() + { + off(); + } + void on() + { + if (!_state) + { + _on(); + } + _state = true; + } + void off() + { + if (_state) + { + _off(); + } + _state = false; + } + + private: + bool _state = false; + std::function _on, _off; +}; + class IPlugObject { public: @@ -90,4 +132,4 @@ class fixedqueue std::atomic_uint32_t _head = 0u; std::atomic_uint32_t _tail = 0u; }; -}; // namespace util \ No newline at end of file +}; // namespace util diff --git a/src/wrapasvst3.cpp b/src/wrapasvst3.cpp index 7a2e011d..97a8204e 100644 --- a/src/wrapasvst3.cpp +++ b/src/wrapasvst3.cpp @@ -60,6 +60,7 @@ tresult PLUGIN_API ClapAsVst3::terminate() { if (_plugin) { + _os_attached.off(); // ensure we are detached _plugin->terminate(); _plugin.reset(); } @@ -87,11 +88,12 @@ tresult PLUGIN_API ClapAsVst3::setActive(TBool state) _expressionmap & clap_supported_note_expressions::AS_VST3_NOTE_EXPRESSION_TUNING); updateAudioBusses(); - os::attach(this); + _os_attached.on(); } if (!state) { - os::detach(this); + _os_attached.off(); + if (_active) { _plugin->deactivate(); diff --git a/src/wrapasvst3.h b/src/wrapasvst3.h index 579bbf33..eca10d7d 100644 --- a/src/wrapasvst3.h +++ b/src/wrapasvst3.h @@ -108,6 +108,7 @@ class ClapAsVst3 : public Steinberg::Vst::SingleComponentEffect, , _library(lib) , _libraryIndex(number) , _creationcontext(context) + , _os_attached([this] { os::attach(this); }, [this] { os::detach(this); }) { } @@ -253,6 +254,7 @@ class ClapAsVst3 : public Steinberg::Vst::SingleComponentEffect, // plugin state bool _active = false; + os::State _os_attached; bool _processing = false; std::mutex _processingLock; std::atomic_bool _requestedFlush = false; From 3e47e813a0660cd42f357507e05b55bfbb853687 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 11 Sep 2023 09:42:27 -0400 Subject: [PATCH 3/3] Refactor the cmake compile options a bit (#129) * Refactor the cmake compile options a bit A few options (like -DPLATFORM=1 and macos filesystem and warnings) were starting to be applied multiple places and not consistently. For instance I had forgotten them on the auv2 build helper. So 1. Make a `clap-wrapper-compile-options` interface which sets up all these things 2. Set it as a link dep of the things which need it 3. Fix the build bugs with the auv2 helper from turning on warnings there and 4. Add an option to likn with asan, which is still a work in progress * Split the sanitize from the warning and platform * Respond to 0ax1 review comments --- cmake/enable_sdks.cmake | 50 ++++++++++++------- src/detail/auv2/auv2_shared.h | 2 +- src/detail/auv2/build-helper/build-helper.cpp | 15 +++--- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/cmake/enable_sdks.cmake b/cmake/enable_sdks.cmake index cbf83f5d..2640b771 100644 --- a/cmake/enable_sdks.cmake +++ b/cmake/enable_sdks.cmake @@ -9,6 +9,7 @@ # make CPM available include(cmake/CPM.cmake) + if (${CLAP_WRAPPER_DOWNLOAD_DEPENDENCIES}) message(STATUS "clap-wrapper: Downloading dependencies using CPM") @@ -247,6 +248,34 @@ if (APPLE) endif() endif() + +add_library(clap-wrapper-compile-options INTERFACE) +add_library(clap-wrapper-sanitizer-options INTERFACE) + +target_compile_options(clap-wrapper-compile-options INTERFACE -D${CLAP_WRAPPER_PLATFORM}=1) +if (APPLE) + target_link_libraries(clap-wrapper-compile-options INTERFACE macos_filesystem_support) +endif() +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") + target_compile_options(clap-wrapper-compile-options INTERFACE -Wall -Wextra -Wno-unused-parameter -Wpedantic -Werror) + if (${CLAP_WRAPPER_ENABLE_SANITIZER}) + message(STATUS "clap-wrapper: enabling sanitizer build") + + target_compile_options(clap-wrapper-sanitizer-options INTERFACE + -fsanitize=address,undefined,float-divide-by-zero + -fsanitize-address-use-after-return=always + -fsanitize-address-use-after-scope + ) + target_link_options(clap-wrapper-sanitizer-options INTERFACE + -fsanitize=address,undefined,float-divide-by-zero + -fsanitize-address-use-after-return=always + -fsanitize-address-use-after-scope + ) + target_link_libraries(clap-wrapper-compile-options INTERFACE clap-wrapper-sanitizer-options) + endif() +endif() + + # define libraries function(target_add_vst3_wrapper) set(oneValueArgs @@ -291,6 +320,7 @@ function(target_add_vst3_wrapper) add_library(base-sdk-vst3 STATIC ${vst3sources}) target_include_directories(base-sdk-vst3 PUBLIC ${VST3_SDK_ROOT} ${VST3_SDK_ROOT}/public.sdk ${VST3_SDK_ROOT}/pluginterfaces) target_compile_options(base-sdk-vst3 PUBLIC $,-DDEVELOPMENT=1,-DRELEASE=1>) # work through steinbergs alternate choices for these + target_link_libraries(base-sdk-vst3 PUBLIC clap-wrapper-sanitizer-options) # The VST3SDK uses sprintf, not snprintf, which macOS flags as deprecated # to move people to snprintf. Silence that warning on the VST3 build if (APPLE) @@ -322,19 +352,11 @@ function(target_add_vst3_wrapper) target_link_libraries(${V3_TARGET}-clap-wrapper-vst3-lib PUBLIC clap base-sdk-vst3) # clap-wrapper-extensions are PUBLIC, so a clap linking the library can access the clap-wrapper-extensions - target_compile_definitions(${V3_TARGET}-clap-wrapper-vst3-lib PUBLIC -D${CLAP_WRAPPER_PLATFORM}=1) - target_link_libraries(${V3_TARGET}-clap-wrapper-vst3-lib PUBLIC clap-wrapper-extensions clap-wrapper-shared-detail) + target_link_libraries(${V3_TARGET}-clap-wrapper-vst3-lib PUBLIC clap-wrapper-extensions clap-wrapper-compile-options clap-wrapper-shared-detail) target_compile_options(${V3_TARGET}-clap-wrapper-vst3-lib PRIVATE -DCLAP_SUPPORTS_ALL_NOTE_EXPRESSIONS=$,1,0> ) - - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") - target_compile_options(${V3_TARGET}-clap-wrapper-vst3-lib PRIVATE -Wall -Wextra -Wno-unused-parameter -Wpedantic -Werror) - endif() - if (APPLE) - target_link_libraries(${V3_TARGET}-clap-wrapper-vst3-lib PUBLIC macos_filesystem_support) - endif() endif() @@ -588,8 +610,7 @@ if (APPLE) target_link_libraries(${AUV2_TARGET}-clap-wrapper-auv2-lib INTERFACE clap base-sdk-auv2) # clap-wrapper-extensions are PUBLIC, so a clap linking the library can access the clap-wrapper-extensions - target_compile_definitions(${AUV2_TARGET}-clap-wrapper-auv2-lib INTERFACE -D${CLAP_WRAPPER_PLATFORM}=1) - target_link_libraries(${AUV2_TARGET}-clap-wrapper-auv2-lib INTERFACE clap-wrapper-extensions clap-wrapper-shared-detail macos_filesystem_support) + target_link_libraries(${AUV2_TARGET}-clap-wrapper-auv2-lib INTERFACE clap-wrapper-extensions clap-wrapper-shared-detail clap-wrapper-compile-options) endif() @@ -653,15 +674,10 @@ add_library(clap-wrapper-shared-detail STATIC src/detail/clap/fsutil.cpp src/detail/clap/automation.h ) -target_compile_options(clap-wrapper-shared-detail PUBLIC -D${CLAP_WRAPPER_PLATFORM}=1) -target_link_libraries(clap-wrapper-shared-detail PUBLIC clap clap-wrapper-extensions) +target_link_libraries(clap-wrapper-shared-detail PUBLIC clap clap-wrapper-extensions clap-wrapper-compile-options) target_include_directories(clap-wrapper-shared-detail PUBLIC libs/fmt) target_include_directories(clap-wrapper-shared-detail PUBLIC src) -if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") - target_compile_options(clap-wrapper-shared-detail PRIVATE -Wall -Wextra -Wno-unused-parameter -Wpedantic -Werror) -endif() - if (APPLE) target_sources(clap-wrapper-shared-detail PRIVATE diff --git a/src/detail/auv2/auv2_shared.h b/src/detail/auv2/auv2_shared.h index 99ce22df..b3f445c9 100644 --- a/src/detail/auv2/auv2_shared.h +++ b/src/detail/auv2/auv2_shared.h @@ -53,7 +53,7 @@ struct ClapBridge if (_clapid.empty()) { - if (_idx < 0 || _idx >= _library.plugins.size()) + if (_idx < 0 || _idx >= (int)_library.plugins.size()) { std::cout << "[ERROR] cannot load by index" << std::endl; return; diff --git a/src/detail/auv2/build-helper/build-helper.cpp b/src/detail/auv2/build-helper/build-helper.cpp index 06b59521..97594ded 100644 --- a/src/detail/auv2/build-helper/build-helper.cpp +++ b/src/detail/auv2/build-helper/build-helper.cpp @@ -132,13 +132,16 @@ bool buildUnitsFromClap(const std::string &clapfile, const std::string &clapname clap_plugin_info_as_auv2_t v2inf; auto res = loader._pluginFactoryAUv2Info->get_auv2_info(loader._pluginFactoryAUv2Info, idx, &v2inf); - if (v2inf.au_type[0] != 0) + if (res) { - u.type = v2inf.au_type; - } - if (v2inf.au_subt[0] != 0) - { - u.subt = v2inf.au_subt; + if (v2inf.au_type[0] != 0) + { + u.type = v2inf.au_type; + } + if (v2inf.au_subt[0] != 0) + { + u.subt = v2inf.au_subt; + } } }