diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f24b204..43163ac 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ on: push: env: - CACHE_VERSION: 28 + CACHE_VERSION: 31 CARDINAL_UNDER_WINE: 1 DEBIAN_FRONTEND: noninteractive HOMEBREW_NO_AUTO_UPDATE: 1 @@ -24,17 +24,6 @@ jobs: with: path: | ~/PawPawBuilds - */*.a - bin/*.*/*.so - bin/*.vst3/Contents/*/*.so - bin/Cardinal - build/Cardinal - build/CardinalFX - build/CardinalSynth - build/plugins - build/rack - carla/build - dpf/build src/Rack/dep/bin src/Rack/dep/include src/Rack/dep/lib @@ -59,15 +48,21 @@ jobs: echo "deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports focal-backports main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list.d/ports-arm64.list sudo apt-get update -qq sudo apt-get install -yqq g++-aarch64-linux-gnu libdbus-1-dev:arm64 libgl1-mesa-dev:arm64 libglib2.0-dev:arm64 libx11-dev:arm64 libxcursor-dev:arm64 libxext-dev:arm64 libxrandr-dev:arm64 qemu-user-static + - name: Set up ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ccache-linux-arm64-v${{ env.CACHE_VERSION }}-${{ env.WITH_LTO }} - name: Build extra dependencies env: PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" ./deps/PawPaw/bootstrap-cardinal.sh linux-aarch64 && ./deps/PawPaw/.cleanup.sh linux-aarch64 - name: Build linux arm64 cross-compiled run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" pushd deps/PawPaw; source local.env linux-aarch64; popd make features make CIBUILD=true NOOPT=true WITH_LTO=${{ env.WITH_LTO }} -j $(nproc) @@ -113,17 +108,6 @@ jobs: with: path: | ~/PawPawBuilds - */*.a - bin/*.*/*.so - bin/*.vst3/Contents/*/*.so - bin/Cardinal - build/Cardinal - build/CardinalFX - build/CardinalSynth - build/plugins - build/rack - carla/build - dpf/build src/Rack/dep/bin src/Rack/dep/include src/Rack/dep/lib @@ -148,15 +132,21 @@ jobs: echo "deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports focal-backports main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list.d/ports-armhf.list sudo apt-get update -qq sudo apt-get install -yqq g++-arm-linux-gnueabihf libdbus-1-dev:armhf libgl1-mesa-dev:armhf libglib2.0-dev:armhf libx11-dev:armhf libxcursor-dev:armhf libxext-dev:armhf libxrandr-dev:armhf qemu-user-static + - name: Set up ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ccache-linux-armhf-v${{ env.CACHE_VERSION }}-${{ env.WITH_LTO }} - name: Build extra dependencies env: PKG_CONFIG_PATH: /usr/lib/arm-linux-gnueabihf/pkgconfig run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" ./deps/PawPaw/bootstrap-cardinal.sh linux-armhf && ./deps/PawPaw/.cleanup.sh linux-armhf - name: Build linux armhf cross-compiled run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" pushd deps/PawPaw; source local.env linux-armhf; popd make features make CIBUILD=true NOOPT=true WITH_LTO=${{ env.WITH_LTO }} -j $(nproc) @@ -202,17 +192,6 @@ jobs: with: path: | ~/PawPawBuilds - */*.a - bin/*.*/*.so - bin/*.vst3/Contents/*/*.so - bin/Cardinal - build/Cardinal - build/CardinalFX - build/CardinalSynth - build/plugins - build/rack - carla/build - dpf/build src/Rack/dep/bin src/Rack/dep/include src/Rack/dep/lib @@ -233,15 +212,21 @@ jobs: sudo dpkg --add-architecture i386 sudo apt-get update -qq sudo apt-get install -yqq g++-multilib libdbus-1-dev:i386 libgl1-mesa-dev:i386 libglib2.0-dev:i386 libx11-dev:i386 libxcursor-dev:i386 libxext-dev:i386 libxrandr-dev:i386 + - name: Set up ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ccache-linux-i686-v${{ env.CACHE_VERSION }}-${{ env.WITH_LTO }} - name: Build extra dependencies env: PKG_CONFIG_PATH: /usr/lib/i386-linux-gnu/pkgconfig run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" ./deps/PawPaw/bootstrap-cardinal.sh linux-i686 && ./deps/PawPaw/.cleanup.sh linux-i686 - name: Build linux i686 run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" pushd deps/PawPaw; source local.env linux-i686; popd make features make CIBUILD=true NOOPT=true WITH_LTO=${{ env.WITH_LTO }} -j $(nproc) @@ -287,17 +272,6 @@ jobs: with: path: | ~/PawPawBuilds - */*.a - bin/*.*/*.so - bin/*.vst3/Contents/*/*.so - bin/Cardinal - build/Cardinal - build/CardinalFX - build/CardinalSynth - build/plugins - build/rack - carla/build - dpf/build src/Rack/dep/bin src/Rack/dep/include src/Rack/dep/lib @@ -312,13 +286,19 @@ jobs: run: | sudo apt-get update -qq sudo apt-get install -yqq libdbus-1-dev libgl1-mesa-dev libglib2.0-dev libx11-dev libxcursor-dev libxext-dev libxrandr-dev + - name: Set up ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ccache-linux-x86_64-v${{ env.CACHE_VERSION }}-${{ env.WITH_LTO }} - name: Build extra dependencies run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" ./deps/PawPaw/bootstrap-cardinal.sh linux && ./deps/PawPaw/.cleanup.sh linux - name: Build linux x86_64 run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" pushd deps/PawPaw; source local.env linux; popd make features make CIBUILD=true NOOPT=true WITH_LTO=${{ env.WITH_LTO }} -j $(nproc) @@ -423,17 +403,6 @@ jobs: with: path: | ~/PawPawBuilds - */*.a - bin/*.*/*.dylib - bin/*.*/Contents/MacOS/* - bin/Cardinal - build/Cardinal - build/CardinalFX - build/CardinalSynth - build/plugins - build/rack - carla/build - dpf/build src/Rack/dep/bin src/Rack/dep/include src/Rack/dep/lib @@ -444,13 +413,19 @@ jobs: src/Rack/dep/speexdsp-SpeexDSP-1.2rc3 src/Rack/dep/zstd-1.4.5 key: macos-intel-v${{ env.CACHE_VERSION }}-${{ env.WITH_LTO }} + - name: Set up ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ccache-macos-intel-v${{ env.CACHE_VERSION }}-${{ env.WITH_LTO }} - name: Build extra dependencies run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/local/opt/ccache/libexec:${PATH}" ./deps/PawPaw/bootstrap-cardinal.sh macos && ./deps/PawPaw/.cleanup.sh macos - name: Build macOS intel (base) run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/local/opt/ccache/libexec:${PATH}" pushd deps/PawPaw; source local.env macos; popd make features make CIBUILD=true NOOPT=true WITH_LTO=${{ env.WITH_LTO }} -j $(sysctl -n hw.logicalcpu) @@ -463,7 +438,7 @@ jobs: git clone --depth=1 -b 6.1.6 https://github.com/juce-framework/JUCE.git jucewrapper/JUCE sed -i -e 's/kAudioUnitProperty_SupportsMPE/kAudioUnitProperty_ignore_SupportsMPE/' jucewrapper/JUCE/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h mkdir -p jucewrapper/build - pushd jucewrapper/build; cmake -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.8 -DCMAKE_OSX_SYSROOT=$(xcrun --sdk macosx --show-sdk-path) -DCMAKE_BUILD_TYPE=Release .. && make VERBOSE=1 -j $(sysctl -n hw.logicalcpu); popd + pushd jucewrapper/build; cmake -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.8 -DCMAKE_OSX_SYSROOT=$(xcrun --sdk macosx --show-sdk-path) -DCMAKE_BUILD_TYPE=Release .. && make VERBOSE=1 -j $(sysctl -n hw.logicalcpu); popd mv jucewrapper/build/*_artefacts/Release/AU/*.component bin/ - name: Build macOS intel (packaging) env: @@ -512,17 +487,6 @@ jobs: with: path: | ~/PawPawBuilds - */*.a - bin/*.*/*.dylib - bin/*.*/Contents/MacOS/* - bin/Cardinal - build/Cardinal - build/CardinalFX - build/CardinalSynth - build/plugins - build/rack - carla/build - dpf/build src/Rack/dep/bin src/Rack/dep/include src/Rack/dep/lib @@ -533,13 +497,19 @@ jobs: src/Rack/dep/speexdsp-SpeexDSP-1.2rc3 src/Rack/dep/zstd-1.4.5 key: macos-universal-v${{ env.CACHE_VERSION }}-${{ env.WITH_LTO }} + - name: Set up ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ccache-macos-universal-v${{ env.CACHE_VERSION }}-${{ env.WITH_LTO }} - name: Build extra dependencies run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/local/opt/ccache/libexec:${PATH}" ./deps/PawPaw/bootstrap-cardinal.sh macos-universal && ./deps/PawPaw/.cleanup.sh macos-universal - name: Build macOS universal (base) run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/local/opt/ccache/libexec:${PATH}" pushd deps/PawPaw; source local.env macos-universal; popd make features make CIBUILD=true NOOPT=true WITH_LTO=${{ env.WITH_LTO }} -j $(sysctl -n hw.logicalcpu) @@ -551,7 +521,7 @@ jobs: pushd deps/PawPaw; source local.env macos-universal; popd git clone --depth=1 -b 6.1.6 https://github.com/juce-framework/JUCE.git jucewrapper/JUCE mkdir -p jucewrapper/build - pushd jucewrapper/build; cmake -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DCMAKE_OSX_SYSROOT=$(xcrun --sdk macosx --show-sdk-path) -DCMAKE_BUILD_TYPE=Release .. && make VERBOSE=1 -j $(sysctl -n hw.logicalcpu); popd + pushd jucewrapper/build; cmake -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 -DCMAKE_OSX_SYSROOT=$(xcrun --sdk macosx --show-sdk-path) -DCMAKE_BUILD_TYPE=Release .. && make VERBOSE=1 -j $(sysctl -n hw.logicalcpu); popd mv jucewrapper/build/*_artefacts/Release/AU/*.component bin/ - name: Build macOS universal (packaging) env: @@ -717,12 +687,6 @@ jobs: with: path: | ~/PawPawBuilds - */*.a - build/CardinalFX - build/plugins - build/rack - carla/build - dpf/build src/Rack/dep/bin src/Rack/dep/include src/Rack/dep/lib @@ -792,11 +756,6 @@ jobs: with: path: | ~/emsdk - */*.a - build/CardinalFX - build/plugins - build/rack - dpf/build src/Rack/dep/bin src/Rack/dep/include src/Rack/dep/lib @@ -864,17 +823,6 @@ jobs: with: path: | ~/PawPawBuilds - */*.a - bin/*.*/*.dll - bin/*.vst3/Contents/*/*.vst3 - bin/Cardinal.exe - build/Cardinal - build/CardinalFX - build/CardinalSynth - build/plugins - build/rack - carla/build - dpf/build src/Rack/dep/bin src/Rack/dep/include src/Rack/dep/lib @@ -896,19 +844,26 @@ jobs: sudo dpkg --add-architecture i386 sudo apt-get update -qq sudo apt-get install -yqq binutils-mingw-w64-i686 g++-mingw-w64-i686 mingw-w64 wine-stable:i386 qttools5-dev qttools5-dev-tools xvfb + - name: Set up ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ccache-win32-v${{ env.CACHE_VERSION }}-${{ env.WITH_LTO }} - name: Build extra dependencies run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" ./deps/PawPaw/bootstrap-cardinal.sh win32 && ./deps/PawPaw/.cleanup.sh win32 - name: Build win32 cross-compiled (base) run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" pushd deps/PawPaw; source local.env win32; popd make features make CIBUILD=true NOOPT=true WITH_LTO=${{ env.WITH_LTO }} -j $(nproc) - name: Build win64 cross-compiled (carla) run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" pushd deps/PawPaw; source local.env win32; popd make -C carla CARLA_BACKEND_NAMESPACE=Cardinal EXTERNAL_PLUGINS=true HAVE_FLUIDSYNTH=false HAVE_ZYN_DEPS=false HAVE_ZYN_UI_DEPS=false HAVE_PYQT=true HAVE_QT5=true HAVE_QT5PKG=true STATIC_PLUGIN_TARGET=true USING_CUSTOM_DPF=true CUSTOM_DPF_PATH=$(pwd)/dpf -j $(nproc) make -C carla EMBED_TARGET=true TESTING=true dist @@ -960,17 +915,6 @@ jobs: with: path: | ~/PawPawBuilds - */*.a - bin/*.*/*.dll - bin/*.vst3/Contents/*/*.vst3 - bin/Cardinal.exe - build/Cardinal - build/CardinalFX - build/CardinalSynth - build/plugins - build/rack - carla/build - dpf/build src/Rack/dep/bin src/Rack/dep/include src/Rack/dep/lib @@ -992,19 +936,26 @@ jobs: sudo dpkg --add-architecture i386 sudo apt-get update -qq sudo apt-get install -yqq binutils-mingw-w64-x86-64 g++-mingw-w64-x86-64 mingw-w64 wine-stable qttools5-dev qttools5-dev-tools xvfb + - name: Set up ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ccache-win64-v${{ env.CACHE_VERSION }}-${{ env.WITH_LTO }} - name: Build extra dependencies run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" ./deps/PawPaw/bootstrap-cardinal.sh win64 && ./deps/PawPaw/.cleanup.sh win64 - name: Build win64 cross-compiled (base) run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" pushd deps/PawPaw; source local.env win64; popd make features make CIBUILD=true NOOPT=true WITH_LTO=${{ env.WITH_LTO }} -j $(nproc) - name: Build win64 cross-compiled (carla) run: | if [ "${{ env.WITH_LTO }}" != "true" ]; then export PAWPAW_SKIP_LTO=1; fi + export PATH="/usr/lib/ccache:${PATH}" pushd deps/PawPaw; source local.env win64; popd make -C carla CARLA_BACKEND_NAMESPACE=Cardinal EXTERNAL_PLUGINS=true HAVE_FLUIDSYNTH=false HAVE_ZYN_DEPS=false HAVE_ZYN_UI_DEPS=false HAVE_PYQT=true HAVE_QT5=true HAVE_QT5PKG=true STATIC_PLUGIN_TARGET=true USING_CUSTOM_DPF=true CUSTOM_DPF_PATH=$(pwd)/dpf all win32r -j $(nproc) make -C carla EMBED_TARGET=true TESTING=true dist @@ -1151,14 +1102,14 @@ jobs: --suppressions=./dpf/utils/valgrind-dpf.supp \ /usr/lib/carla/carla-bridge-native vst2 ./${p} "" 1>/dev/null; \ done - #- name: Test VST3 plugin - #run: | - #for p in $(ls bin/ | grep vst3); do \ - #env CARLA_BRIDGE_DUMMY=1 CARLA_BRIDGE_TESTING=native \ - #valgrind \ - #--error-exitcode=255 \ - #--leak-check=no \ - #--track-origins=yes \ - #--suppressions=./dpf/utils/valgrind-dpf.supp \ - #/usr/lib/carla/carla-bridge-native vst3 ./bin/${p} "" 1>/dev/null; \ - #done + - name: Test VST3 plugin + run: | + for p in $(ls bin/ | grep vst3); do \ + env CARLA_BRIDGE_DUMMY=1 CARLA_BRIDGE_TESTING=native \ + valgrind \ + --error-exitcode=255 \ + --leak-check=no \ + --track-origins=yes \ + --suppressions=./dpf/utils/valgrind-dpf.supp \ + /usr/lib/carla/carla-bridge-native vst3 ./bin/${p} "" 1>/dev/null; \ + done diff --git a/deps/Makefile b/deps/Makefile index 96b61c9..e4d1db9 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -66,15 +66,12 @@ BUILD_CXX_FLAGS += -U_GLIBCXX_ASSERTIONS -Wp,-U_GLIBCXX_ASSERTIONS # -------------------------------------------------------------- # override VCV arch.mk stuff so we can build more architectures -ifeq ($(CPU_AARCH64),true) -ARCH_NAME = aarch64 -MACHINE = x86_64-the-rack +ifeq ($(CPU_ARM32),true) +ARCH_NAME = arm +MACHINE = i686-the-rack else ifeq ($(CPU_ARM64),true) ARCH_NAME = arm64 MACHINE = x86_64-the-rack -else ifeq ($(CPU_ARM),true) -ARCH_NAME = arm -MACHINE = i686-the-rack else ifeq ($(WASM),true) MACHINE = i686-wasm else diff --git a/deps/PawPaw b/deps/PawPaw index 102ebdf..4f7f9eb 160000 --- a/deps/PawPaw +++ b/deps/PawPaw @@ -1 +1 @@ -Subproject commit 102ebdff3963b6e3e70e5f29c02225b6ae7b64e5 +Subproject commit 4f7f9eb6ff1677606a85fe701bbb535f8fe7086c diff --git a/dpf b/dpf index 352bcbf..923c4fb 160000 --- a/dpf +++ b/dpf @@ -1 +1 @@ -Subproject commit 352bcbfb7268d7ba8badb3be6b06cbef74c1bbc2 +Subproject commit 923c4fbca043b5a0a69226b738dbf9fac1c087f2 diff --git a/plugins/Makefile b/plugins/Makefile index ed6c6b3..767a3fa 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -1042,10 +1042,7 @@ BASE_FLAGS += -ffat-lto-objects endif endif -ifeq ($(BSD),true) -BASE_FLAGS += -D'aligned_alloc_16(ptr)'='aligned_alloc(16,ptr)' -BASE_FLAGS += -D'aligned_free_16(ptr)'='free(ptr)' -else ifeq ($(WASM),true) +ifeq ($(BSD)$(WASM),true) BASE_FLAGS += -D'aligned_alloc_16(ptr)'='aligned_alloc(16,ptr)' BASE_FLAGS += -D'aligned_free_16(ptr)'='free(ptr)' endif diff --git a/src/CardinalCommon.cpp b/src/CardinalCommon.cpp index 5f3f4ef..a67d446 100644 --- a/src/CardinalCommon.cpp +++ b/src/CardinalCommon.cpp @@ -98,6 +98,8 @@ std::string getSpecialPath(const SpecialPath type) #endif #ifdef DISTRHO_OS_WASM +char* patchFromURL = nullptr; +char* patchRemoteURL = nullptr; char* patchStorageSlug = nullptr; #endif diff --git a/src/CardinalCommon.hpp b/src/CardinalCommon.hpp index cb3d1b4..188a454 100644 --- a/src/CardinalCommon.hpp +++ b/src/CardinalCommon.hpp @@ -26,7 +26,6 @@ #endif #ifdef DISTRHO_OS_WASM -# define CARDINAL_WASM_IMPORTED_TEMPLATE_FILENAME "/imported.vcv" # ifdef STATIC_BUILD # define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm-mini.vcv" # else @@ -59,6 +58,8 @@ std::string getSpecialPath(SpecialPath type); #endif #ifdef DISTRHO_OS_WASM +extern char* patchFromURL; +extern char* patchRemoteURL; extern char* patchStorageSlug; #endif diff --git a/src/CardinalPlugin.cpp b/src/CardinalPlugin.cpp index 5eb1e95..bfd2f1e 100644 --- a/src/CardinalPlugin.cpp +++ b/src/CardinalPlugin.cpp @@ -104,6 +104,32 @@ bool d_isDiffHigherThanLimit(const T& v1, const T& v2, const T& limit) // ----------------------------------------------------------------------------------------------------------- #ifdef DISTRHO_OS_WASM +static char* getPatchFileEncodedInURL() { + return static_cast(EM_ASM_PTR({ + var searchParams = new URLSearchParams(window.location.search); + var patch = searchParams.get('patch'); + if (!patch) + return null; + var length = lengthBytesUTF8(patch) + 1; + var str = _malloc(length); + stringToUTF8(patch, str, length); + return str; + })); +}; + +static char* getPatchRemoteURL() { + return static_cast(EM_ASM_PTR({ + var searchParams = new URLSearchParams(window.location.search); + var patch = searchParams.get('patchurl'); + if (!patch) + return null; + var length = lengthBytesUTF8(patch) + 1; + var str = _malloc(length); + stringToUTF8(patch, str, length); + return str; + })); +}; + static char* getPatchStorageSlug() { return static_cast(EM_ASM_PTR({ var searchParams = new URLSearchParams(window.location.search); @@ -606,7 +632,9 @@ public: context->window = new rack::window::Window; #ifdef DISTRHO_OS_WASM - if ((rack::patchStorageSlug = getPatchStorageSlug()) == nullptr) + if ((rack::patchStorageSlug = getPatchStorageSlug()) == nullptr && + (rack::patchRemoteURL = getPatchRemoteURL()) == nullptr && + (rack::patchFromURL = getPatchFileEncodedInURL()) == nullptr) #endif { context->patch->loadTemplate(); @@ -1143,11 +1171,29 @@ protected: const std::vector data(d_getChunkFromBase64String(value)); + DISTRHO_SAFE_ASSERT_RETURN(data.size() >= 4,); + const ScopedContext sc(this); rack::system::removeRecursively(fAutosavePath); rack::system::createDirectories(fAutosavePath); - rack::system::unarchiveToDirectory(data, fAutosavePath); + + static constexpr const char zstdMagic[] = "\x28\xb5\x2f\xfd"; + + if (std::memcmp(data.data(), zstdMagic, sizeof(zstdMagic)) != 0) + { + FILE* const f = std::fopen(rack::system::join(fAutosavePath, "patch.json").c_str(), "w"); + DISTRHO_SAFE_ASSERT_RETURN(f != nullptr,); + + std::fwrite(data.data(), data.size(), 1, f); + std::fclose(f); + } + else + { + try { + rack::system::unarchiveToDirectory(data, fAutosavePath); + } DISTRHO_SAFE_EXCEPTION_RETURN("setState unarchiveToDirectory",); + } try { context->patch->loadAutosave(); diff --git a/src/CardinalUI.cpp b/src/CardinalUI.cpp index 21ac7e4..17f85ee 100644 --- a/src/CardinalUI.cpp +++ b/src/CardinalUI.cpp @@ -191,24 +191,24 @@ struct WasmWelcomeDialog : rack::widget::OpaqueWidget } }; -struct WasmPatchStorageLoadingDialog : rack::widget::OpaqueWidget +struct WasmRemotePatchLoadingDialog : rack::widget::OpaqueWidget { static const constexpr float margin = 10; rack::ui::MenuOverlay* overlay; - WasmPatchStorageLoadingDialog() + WasmRemotePatchLoadingDialog(const bool isFromPatchStorage) { using rack::ui::Label; using rack::ui::MenuOverlay; using rack::ui::SequentialLayout; - box.size = rack::math::Vec(300, 50); + box.size = rack::math::Vec(300, 40); SequentialLayout* const layout = new SequentialLayout; layout->box.pos = rack::math::Vec(0, 0); layout->box.size = box.size; - layout->orientation = SequentialLayout::VERTICAL_ORIENTATION; + layout->alignment = SequentialLayout::CENTER_ALIGNMENT; layout->margin = rack::math::Vec(margin, margin); layout->spacing = rack::math::Vec(margin, margin); layout->wrap = false; @@ -216,9 +216,11 @@ struct WasmPatchStorageLoadingDialog : rack::widget::OpaqueWidget Label* const label = new Label; label->box.size.x = box.size.x - 2*margin; - label->box.size.y = box.size.y - 2*margin - 40; + label->box.size.y = box.size.y - 2*margin; label->fontSize = 16; - label->text = "Load patch from PatchStorage...\n"; + label->text = isFromPatchStorage + ? "Loading patch from PatchStorage...\n" + : "Loading remote patch...\n"; layout->addChild(label); overlay = new MenuOverlay; @@ -240,16 +242,17 @@ struct WasmPatchStorageLoadingDialog : rack::widget::OpaqueWidget } }; -static void downloadPatchStorageFailed(const char* const filename) +static void downloadRemotePatchFailed(const char* const filename) { - d_stdout("downloadPatchStorageFailed %s", filename); + d_stdout("downloadRemotePatchFailed %s", filename); CardinalPluginContext* const context = static_cast(APP); CardinalBaseUI* const ui = static_cast(context->ui); if (ui->psDialog != nullptr) { ui->psDialog->overlay->requestDelete(); - asyncDialog::create("Failed to fetch patch from PatchStorage"); + ui->psDialog = nullptr; + asyncDialog::create("Failed to fetch remote patch"); } using namespace rack; @@ -258,9 +261,9 @@ static void downloadPatchStorageFailed(const char* const filename) context->scene->rackScroll->reset(); } -static void downloadPatchStorageSucceeded(const char* const filename) +static void downloadRemotePatchSucceeded(const char* const filename) { - d_stdout("downloadPatchStorageSucceeded %s | %s", filename, APP->patch->templatePath.c_str()); + d_stdout("downloadRemotePatchSucceeded %s | %s", filename, APP->patch->templatePath.c_str()); CardinalPluginContext* const context = static_cast(APP); CardinalBaseUI* const ui = static_cast(context->ui); @@ -277,7 +280,7 @@ static void downloadPatchStorageSucceeded(const char* const filename) } try { - context->patch->load(CARDINAL_WASM_IMPORTED_TEMPLATE_FILENAME); + context->patch->load(filename); } catch (rack::Exception& e) { const std::string message = rack::string::f("Could not load patch: %s", e.what()); asyncDialog::create(message.c_str()); @@ -388,9 +391,22 @@ public: #ifdef DISTRHO_OS_WASM if (rack::patchStorageSlug != nullptr) - psDialog = new WasmPatchStorageLoadingDialog(); + { + psDialog = new WasmRemotePatchLoadingDialog(true); + } + else if (rack::patchRemoteURL != nullptr) + { + psDialog = new WasmRemotePatchLoadingDialog(false); + } + else if (rack::patchFromURL != nullptr) + { + static_cast(context->plugin)->setState("patch", rack::patchFromURL); + rack::contextSet(context); + } else + { new WasmWelcomeDialog(); + } #endif context->window->step(); @@ -441,7 +457,17 @@ public: rack::patchStorageSlug = nullptr; emscripten_async_wget(url.c_str(), context->patch->templatePath.c_str(), - downloadPatchStorageSucceeded, downloadPatchStorageFailed); + downloadRemotePatchSucceeded, downloadRemotePatchFailed); + } + else if (rack::patchRemoteURL != nullptr) + { + std::string url("/patchurl.php?url="); + url += rack::patchRemoteURL; + std::free(rack::patchRemoteURL); + rack::patchRemoteURL = nullptr; + + emscripten_async_wget(url.c_str(), context->patch->templatePath.c_str(), + downloadRemotePatchSucceeded, downloadRemotePatchFailed); } #endif } diff --git a/src/PluginContext.hpp b/src/PluginContext.hpp index 558260f..c5a2292 100644 --- a/src/PluginContext.hpp +++ b/src/PluginContext.hpp @@ -135,10 +135,14 @@ public: : Plugin(parameterCount, programCount, stateCount), context(new CardinalPluginContext(this)) {} ~CardinalBasePlugin() override {} + +#ifndef HEADLESS + friend class CardinalUI; +#endif }; #ifndef HEADLESS -struct WasmPatchStorageLoadingDialog; +struct WasmRemotePatchLoadingDialog; class CardinalBaseUI : public UI { public: @@ -147,7 +151,7 @@ public: bool savingUncompressed; #ifdef DISTRHO_OS_WASM - WasmPatchStorageLoadingDialog* psDialog; + WasmRemotePatchLoadingDialog* psDialog; #endif // for 3rd party modules