diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5429fcf..e479b9e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,23 +3,34 @@ name: build on: [push, pull_request] env: - CACHE_VERSION: 4 + CACHE_VERSION: 7 CARDINAL_UNDER_WINE: 1 CIBUILD: true - EMSCRIPTEN_VERSION: 3.1.27 + DEBIAN_FRONTEND: noninteractive LIBGL_ALWAYS_SOFTWARE: true - PAWPAW_SKIP_LTO: 1 PAWPAW_SKIP_GLIB: 1 + PAWPAW_SKIP_LTO: 1 PAWPAW_SKIP_LV2: 1 + PAWPAW_SKIP_OPENSSL: 1 PAWPAW_SKIP_SAMPLERATE: 1 + PAWPAW_SKIP_TESTS: 1 jobs: linux: strategy: matrix: - target: [aarch64, armhf, i386, riscv64, x86_64] - runs-on: ubuntu-20.04 + target: [aarch64, armhf, i686, riscv64, x86_64] + runs-on: ubuntu-latest + container: + image: ubuntu:20.04 steps: + - name: Install git + run: | + apt-get update -qq && apt-get install -yqq --no-install-recommends ca-certificates curl git openssl + curl -sLO https://launchpad.net/~kxstudio-debian/+archive/ubuntu/toolchain/+files/git_2.34.1-1ubuntu1~bpo20.04.1~ppa1_amd64.deb + curl -sLO https://launchpad.net/~kxstudio-debian/+archive/ubuntu/toolchain/+files/git-man_2.34.1-1ubuntu1~bpo20.04.1~ppa1_all.deb + dpkg -i *.deb + rm *.deb - uses: actions/checkout@v3 with: submodules: recursive @@ -38,83 +49,55 @@ jobs: src/Rack/dep/libsamplerate-0.1.9 src/Rack/dep/zstd-1.4.5 key: linux-${{ matrix.target }}-v${{ env.CACHE_VERSION }} - - name: Fix GitHub's mess + - name: Setup dependencies + shell: bash run: | - sudo rm /etc/apt/sources.list.d/*.list - sudo apt-get update -qq - sudo apt-get purge -yqq git-man libclang* libgbm* libllvm* libmono* libnginx* moby* mono* nginx* perl php* libgdiplus libpcre2-posix3 libselinux1-dev libzip4 - sudo apt-get install -yqq --allow-downgrades autoconf/focal automake/focal build-essential/focal git/focal libgd3/focal libglib2.0-0/focal libglib2.0-dev/focal libpcre2-8-0/focal libpcre2-16-0/focal libpcre2-32-0/focal libpcre2-posix2/focal pkg-config/focal - sudo apt-get clean + ./deps/PawPaw/.github/workflows/bootstrap-deps.sh linux-${{ matrix.target }} + apt-get install -yqq wget zip - name: Setup dependencies (aarch64) if: ${{ matrix.target == 'aarch64' }} shell: bash run: | - sudo dpkg --add-architecture arm64 - sudo sed -i "s/deb http/deb [arch=amd64] http/" /etc/apt/sources.list - sudo sed -i "s/deb mirror/deb [arch=amd64] mirror/" /etc/apt/sources.list - echo "deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports focal main restricted universe multiverse" | sudo tee /etc/apt/sources.list.d/ports-arm64.list - echo "deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports focal-updates main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list.d/ports-arm64.list - 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 libasound2-dev:arm64 libdbus-1-dev:arm64 libgl1-mesa-dev:arm64 libglib2.0-dev:arm64 libsdl2-dev:arm64 libx11-dev:arm64 libxcursor-dev:arm64 libxext-dev:arm64 libxrandr-dev:arm64 gperf meson qemu-user-static - sudo apt-get clean + apt-get install -yqq libsdl2-dev:arm64 + apt-get clean - name: Setup dependencies (armhf) if: ${{ matrix.target == 'armhf' }} shell: bash run: | - sudo dpkg --add-architecture armhf - sudo sed -i "s/deb http/deb [arch=amd64] http/" /etc/apt/sources.list - sudo sed -i "s/deb mirror/deb [arch=amd64] mirror/" /etc/apt/sources.list - echo "deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports focal main restricted universe multiverse" | sudo tee /etc/apt/sources.list.d/ports-armhf.list - echo "deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports focal-updates main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list.d/ports-armhf.list - 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 libasound2-dev:armhf libdbus-1-dev:armhf libgl1-mesa-dev:armhf libglib2.0-dev:armhf libsdl2-dev:armhf libx11-dev:armhf libxcursor-dev:armhf libxext-dev:armhf libxrandr-dev:armhf gperf meson qemu-user-static - sudo apt-get clean - - name: Setup dependencies (i386) - if: ${{ matrix.target == 'i386' }} + apt-get install -yqq libsdl2-dev:armhf + apt-get clean + - name: Setup dependencies (i686) + if: ${{ matrix.target == 'i686' }} shell: bash run: | - sudo dpkg --add-architecture i386 - sudo apt-get update -qq - sudo apt-get install -yqq g++-i686-linux-gnu libasound2-dev:i386 libdbus-1-dev:i386 libgl1-mesa-dev:i386 libglib2.0-dev:i386 libsdl2-dev:i386 libx11-dev:i386 libxcursor-dev:i386 libxext-dev:i386 libxrandr-dev:i386 gperf meson - sudo apt-get clean + apt-get install -yqq libsdl2-dev:i386 + apt-get clean - name: Setup dependencies (riscv64) if: ${{ matrix.target == 'riscv64' }} shell: bash run: | - sudo dpkg --add-architecture riscv64 - sudo sed -i "s/deb http/deb [arch=amd64] http/" /etc/apt/sources.list - sudo sed -i "s/deb mirror/deb [arch=amd64] mirror/" /etc/apt/sources.list - echo "deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports focal main restricted universe multiverse" | sudo tee /etc/apt/sources.list.d/ports-riscv64.list - echo "deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports focal-updates main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list.d/ports-riscv64.list - echo "deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports focal-backports main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list.d/ports-riscv64.list - sudo apt-get update -qq - sudo apt-get install -yqq g++-riscv64-linux-gnu libasound2-dev:riscv64 libdbus-1-dev:riscv64 libgl1-mesa-dev:riscv64 libglapi-mesa:riscv64 libglvnd0:riscv64 libglib2.0-dev:riscv64 libsdl2-dev:riscv64 libx11-dev:riscv64 libxcursor-dev:riscv64 libxext-dev:riscv64 libxrandr-dev:riscv64 gperf meson qemu-user-static - sudo apt-get clean + apt-get install -yqq libsdl2-dev:riscv64 + apt-get clean - name: Setup dependencies (x86_64) if: ${{ matrix.target == 'x86_64' }} shell: bash run: | - sudo apt-get update -qq - sudo apt-get install -yqq libasound2-dev libdbus-1-dev libgl1-mesa-dev libglib2.0-dev libsdl2-dev libx11-dev libxcursor-dev libxext-dev libxrandr-dev gperf meson - sudo apt-get clean + apt-get install -yqq libsdl2-dev + apt-get clean - name: Set up ccache uses: hendrikmuhs/ccache-action@v1.2 with: key: ccache-linux-${{ matrix.target }}-v${{ env.CACHE_VERSION }} - name: Build extra dependencies - env: - PKG_CONFIG_PATH: /usr/lib/${{ matrix.target }}-linux-gnu/pkgconfig run: | ./deps/PawPaw/bootstrap-cardinal.sh linux-${{ matrix.target }} && ./deps/PawPaw/.cleanup.sh linux-${{ matrix.target }} - name: Build linux + shell: bash run: | export PATH="/usr/lib/ccache:${PATH}" source deps/PawPaw/local.env linux-${{ matrix.target }} - export PKG_CONFIG_PATH+=:/usr/lib/${{ matrix.target }}-linux-gnu/pkgconfig make features - make HAVE_PULSEAUDIO=false NOOPT=true -j $(nproc) + make HAVE_PULSEAUDIO=false NOOPT=true USING_GLES2=${{ matrix.target == 'aarch64' || matrix.target == 'armhf' }} -j $(nproc) make unzipfx - name: Set sha8 (non-release) if: startsWith(github.ref, 'refs/tags/') != true @@ -198,7 +181,7 @@ jobs: key: macos-${{ matrix.target }}-v${{ env.CACHE_VERSION }} - name: Setup dependencies run: | - brew install autoconf automake meson + ./deps/PawPaw/.github/workflows/bootstrap-deps.sh macos-${{ matrix.target }} - name: Build extra dependencies run: | export PATH="/usr/local/opt/ccache/libexec:${PATH}" @@ -210,6 +193,7 @@ jobs: key: ccache-macos-${{ matrix.target }}-v${{ env.CACHE_VERSION }} - name: Build macOS (base) if: steps.cache.outputs.cache-hit == 'true' + shell: bash run: | export PATH="/usr/local/opt/ccache/libexec:${PATH}" source deps/PawPaw/local.env macos-${{ matrix.target }} @@ -217,6 +201,7 @@ jobs: make NOOPT=true -j $(sysctl -n hw.logicalcpu) - name: Build macOS (AU using juce) if: steps.cache.outputs.cache-hit == 'true' + shell: bash run: | export PATH="/usr/local/opt/ccache/libexec:${PATH}" source deps/PawPaw/local.env macos-${{ matrix.target }} @@ -225,6 +210,7 @@ jobs: mv jucewrapper/build/*_artefacts/Release/AU/*.component bin/ - name: Build macOS (packaging) if: steps.cache.outputs.cache-hit == 'true' + shell: bash run: | source deps/PawPaw/local.env macos-${{ matrix.target }} ./utils/create-macos-installer.sh @@ -335,18 +321,15 @@ jobs: sudo apt-get update -qq sudo apt-get install -yqq brotli gperf meson sudo apt-get clean - [ -e ~/PawPawBuilds/emsdk ] || git clone https://github.com/emscripten-core/emsdk.git ~/PawPawBuilds/emsdk - cd ~/PawPawBuilds/emsdk && ./emsdk install ${{ env.EMSCRIPTEN_VERSION }} && ./emsdk activate ${{ env.EMSCRIPTEN_VERSION }} - name: Build extra dependencies run: | ${{ matrix.target == 'nosimd' }} && export PAWPAW_NOSIMD=1 - source ~/PawPawBuilds/emsdk/emsdk_env.sh ./deps/PawPaw/bootstrap-cardinal.sh wasm && ./deps/PawPaw/.cleanup.sh wasm - name: Build wasm cross-compiled if: steps.cache.outputs.cache-hit == 'true' + shell: bash run: | ${{ matrix.target == 'nosimd' }} && export PAWPAW_NOSIMD=1 - source ~/PawPawBuilds/emsdk/emsdk_env.sh source deps/PawPaw/local.env wasm # FIXME send patch upstream, assuming this works.. sed -i -e 's/defined(__riscv)/defined(__riscv) || defined(__EMSCRIPTEN__)/' plugins/surgext/surge/src/common/globals.h @@ -354,13 +337,14 @@ jobs: make HAVE_LIBLO=false NOOPT=true NOSIMD=${{ matrix.target == 'nosimd' }} -j $(nproc) - name: Build modgui if: steps.cache.outputs.cache-hit == 'true' + shell: bash run: | ${{ matrix.target == 'nosimd' }} && export PAWPAW_NOSIMD=1 - source ~/PawPawBuilds/emsdk/emsdk_env.sh source deps/PawPaw/local.env wasm make HAVE_LIBLO=false NOOPT=true NOSIMD=${{ matrix.target == 'nosimd' }} -j $(nproc) -C src/CardinalMiniSep modgui - name: Make wasm versioned and compress if: steps.cache.outputs.cache-hit == 'true' + shell: bash run: | ${{ matrix.target == 'nosimd' }} && export SUFFIX="-nosimd" VERSION=$(cat Makefile | awk 'sub("VERSION = ","")') @@ -405,8 +389,13 @@ jobs: strategy: matrix: target: [win32, win64] - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest + container: + image: ubuntu:22.04 steps: + - name: Install git + run: | + apt-get update -qq && apt-get install -yqq --no-install-recommends ca-certificates git openssl - uses: actions/checkout@v3 with: submodules: recursive @@ -425,23 +414,11 @@ jobs: src/Rack/dep/libsamplerate-0.1.9 src/Rack/dep/zstd-1.4.5 key: ${{ matrix.target }}-v${{ env.CACHE_VERSION }} - - name: Fix GitHub's mess - run: | - sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list - sudo dpkg --add-architecture i386 - sudo apt-get update -qq - sudo apt-get install -yqq --allow-downgrades libc6:i386 libgcc-s1:i386 libstdc++6:i386 - sudo apt-get clean - name: Set up dependencies - if: ${{ matrix.target == 'win32' }} run: | - sudo apt-get install -yqq binutils-mingw-w64-i686 g++-mingw-w64-i686 mingw-w64 wine-stable:i386 gperf meson qttools5-dev qttools5-dev-tools xvfb - sudo apt-get clean - - name: Set up dependencies - if: ${{ matrix.target == 'win64' }} - run: | - sudo apt-get install -yqq binutils-mingw-w64-x86-64 g++-mingw-w64-x86-64 mingw-w64 wine-stable gperf meson qttools5-dev qttools5-dev-tools xvfb - sudo apt-get clean + ./deps/PawPaw/.github/workflows/bootstrap-deps.sh ${{ matrix.target }} + apt-get install -yqq wget xvfb zip + apt-get clean - name: Set up ccache uses: hendrikmuhs/ccache-action@v1.2 with: @@ -451,6 +428,7 @@ jobs: ./deps/PawPaw/bootstrap-cardinal.sh ${{ matrix.target }} && ./deps/PawPaw/.cleanup.sh ${{ matrix.target }} - name: Build cross-compiled (base) if: steps.cache.outputs.cache-hit == 'true' + shell: bash run: | export PATH="/usr/lib/ccache:${PATH}" source deps/PawPaw/local.env ${{ matrix.target }} @@ -458,6 +436,7 @@ jobs: make NOOPT=true -j $(nproc) - name: Build cross-compiled (carla) if: steps.cache.outputs.cache-hit == 'true' + shell: bash run: | export PATH="/usr/lib/ccache:${PATH}" source deps/PawPaw/local.env ${{ matrix.target }} @@ -466,6 +445,7 @@ jobs: make -C carla EMBED_TARGET=true TESTING=true dist - name: Build cross-compiled (packaging) if: steps.cache.outputs.cache-hit == 'true' + shell: bash run: | source deps/PawPaw/local.env ${{ matrix.target }} xvfb-run ./utils/create-windows-installer.sh ${{ matrix.target }} @@ -478,6 +458,7 @@ jobs: run: echo "SHA8=$(echo ${{ github.ref_name }})" >> $GITHUB_ENV - name: Pack binaries if: steps.cache.outputs.cache-hit == 'true' + shell: bash run: | pushd bin zip -r -9 ../${{ github.event.repository.name }}-${{ matrix.target }}-${{ github.event.pull_request.number || env.SHA8 }}.zip $(ls | grep -e lv2 -e vst -e clap) diff --git a/.gitmodules b/.gitmodules index 7c83b4c..56ea39a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -212,9 +212,6 @@ [submodule "plugins/dBiz"] path = plugins/dBiz url = https://github.com/dBiz/dBiz.git -[submodule "include/simde"] - path = include/simde - url = https://github.com/simd-everywhere/simde.git [submodule "plugins/RebelTech"] path = plugins/RebelTech url = https://github.com/hemmer/rebel-tech-vcv.git @@ -233,6 +230,9 @@ [submodule "plugins/EnigmaCurry"] path = plugins/EnigmaCurry url = https://github.com/EnigmaCurry/EnigmaCurry-vcv-pack.git +[submodule "plugins/DHE-Modules"] + path = plugins/DHE-Modules + url = https://github.com/dhemery/DHE-Modules.git [submodule "plugins/StarlingVia"] path = plugins/StarlingVia url = https://github.com/starlingcode/Via-for-Rack.git diff --git a/Makefile b/Makefile index e2c3a6b..57d0d12 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,7 @@ #!/usr/bin/make -f -# Makefile for DISTRHO Plugins # -# ---------------------------- # -# Created by falkTX -# +# DISTRHO Cardinal Plugin +# Copyright (C) 2021-2024 Filipe Coelho +# SPDX-License-Identifier: GPL-3.0-or-later ROOT = . include $(ROOT)/Makefile.base.mk @@ -16,7 +15,7 @@ include $(ROOT)/Makefile.base.mk # src/CardinalPlugin.cpp `getVersion` # utils/macOS/Info_{JACK,Native}.plist # jucewrapper/CMakeLists.txt src/CardinalCommon.cpp src/CardinalPlugin.cpp utils/macOS/Info_{JACK,Native}.plist -VERSION = 23.10 +VERSION = 24.01 # -------------------------------------------------------------- # Build targets @@ -268,9 +267,6 @@ clean: $(MAKE) clean -C plugins $(MAKE) clean -C src rm -rf bin build build-headless dpf/utils/lv2_ttl_generator.d - # FIXME - rm -f src/Rack/BaconMusic/default-skin.json - rm -f src/Rack/SurgeXTRack/default-skin.json # -------------------------------------------------------------- # Install step diff --git a/Makefile.base.mk b/Makefile.base.mk index c4cbcff..9c5097f 100644 --- a/Makefile.base.mk +++ b/Makefile.base.mk @@ -68,6 +68,12 @@ endif ifeq ($(NOSIMD),true) BASE_FLAGS += -DCARDINAL_NOSIMD +else ifeq ($(WASM),true) +BASE_FLAGS += -msse -msse2 -msse3 -msimd128 +else ifeq ($(CPU_ARM32),true) +BASE_FLAGS += -mfpu=neon-vfpv4 -mfloat-abi=hard +else ifeq ($(CPU_I386_OR_X86_64),true) +BASE_FLAGS += -msse -msse2 -msse3 endif ifeq ($(SYSDEPS),true) @@ -109,10 +115,6 @@ BASE_FLAGS += -DSIMDE_FAST_NANS BASE_FLAGS += -DSIMDE_FAST_ROUND_MODE BASE_FLAGS += -DSIMDE_FAST_ROUND_TIES -# unwanted -BASE_FLAGS += -DSIMDE_X86_SSE4_1_H -BASE_FLAGS += -DSIMDE_X86_SSE4_2_H - # ----------------------------------------------------------------------------- # Rack build flags @@ -153,33 +155,16 @@ ifeq ($(HEADLESS),true) BASE_FLAGS += -DHEADLESS endif -ifeq ($(USE_GLES2),true) -BASE_FLAGS += -DNANOVG_GLES2_FORCED -else ifeq ($(USE_GLES3),true) +ifeq ($(USE_GLES3),true) BASE_FLAGS += -DNANOVG_GLES3_FORCED +else ifeq ($(USE_GLES2),true) +BASE_FLAGS += -DNANOVG_GLES2_FORCED endif # needed for enabling SSE in pffft ifeq ($(CPU_I386),true) -ifneq ($(NOSIMD),true) BASE_FLAGS += -Di386 endif -endif - -# SIMD must always be enabled, even in debug builds -ifneq ($(NOSIMD),true) -ifeq ($(DEBUG),true) - -ifeq ($(WASM),true) -BASE_FLAGS += -msse -msse2 -msse3 -msimd128 -else ifeq ($(CPU_ARM32),true) -BASE_FLAGS += -mfpu=neon-vfpv4 -mfloat-abi=hard -else ifeq ($(CPU_I386_OR_X86_64),true) -BASE_FLAGS += -msse -msse2 -mfpmath=sse -endif - -endif -endif BASE_FLAGS += -I$(abspath $(ROOT)/dpf/dgl/src/nanovg) BASE_FLAGS += -I$(abspath $(ROOT)/dpf/distrho) diff --git a/README.md b/README.md index 8224ac1..7e9238a 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,7 @@ At the moment the following 3rd-party modules are provided: - [cf](https://github.com/cfoulc/cf) - [ChowDSP](https://github.com/jatinchowdhury18/ChowDSP-VCV) - [dBiz](https://github.com/dBiz/dBiz) +- [DHE Modules](https://github.com/dhemery/DHE-Modules) - [DrumKit](https://svmodular.com/plugin/vcv/drumkit.html) - [EnigmaCurry](https://github.com/EnigmaCurry/EnigmaCurry-vcv-pack) - [E-Series](https://github.com/VCVRack/ESeries) diff --git a/carla b/carla index 41f07e1..c2031ed 160000 --- a/carla +++ b/carla @@ -1 +1 @@ -Subproject commit 41f07e119252b8b14627bec8345cb7304485a815 +Subproject commit c2031edc1c82c3e760394b6363627caf25a7c256 diff --git a/deps/Makefile b/deps/Makefile index 4d32cd2..5e70651 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -269,19 +269,6 @@ endif # use custom JUCE from DISTRHO and Carla SURGE_CXX_FLAGS += -I$(abspath ../carla/source/modules) -# SIMD must always be enabled, even in debug builds -ifeq ($(NOSIMD),true) -SURGE_CXX_FLAGS += -DCARDINAL_NOSIMD -else ifeq ($(DEBUG),true) -ifeq ($(WASM),true) -SURGE_CXX_FLAGS += -msse -msse2 -msse3 -msimd128 -else ifeq ($(CPU_ARM32),true) -SURGE_CXX_FLAGS += -mfpu=neon-vfpv4 -mfloat-abi=hard -else ifeq ($(CPU_I386_OR_X86_64),true) -SURGE_CXX_FLAGS += -msse -msse2 -mfpmath=sse -endif -endif - # possibly use fftw? # ifeq ($(shell $(PKG_CONFIG) --exists fftw3 fftw3f && echo true),true) # SURGE_CXX_FLAGS += -DJUCE_DSP_USE_STATIC_FFTW=1 @@ -348,6 +335,12 @@ clean: rm -rf $(RACK_DEP_PATH)/jansson-2.12 rm -rf $(RACK_DEP_PATH)/libarchive-3.4.3 rm -rf $(RACK_DEP_PATH)/libsamplerate-0.1.9 + rm -rf $(RACK_DEP_PATH)/speexdsp/autom4te.cache + rm -rf $(RACK_DEP_PATH)/speexdsp/libspeexdsp/.deps + rm -rf $(RACK_DEP_PATH)/speexdsp/libspeexdsp/.libs + rm -rf $(RACK_DEP_PATH)/speexdsp/libspeexdsp/*.lo + rm -rf $(RACK_DEP_PATH)/speexdsp/libspeexdsp/*.o + rm -rf $(RACK_DEP_PATH)/speexdsp/Makefile rm -rf $(RACK_DEP_PATH)/zstd-1.4.5 rm -rf $(SURGE_DEP_PATH) diff --git a/deps/PawPaw b/deps/PawPaw index 6a3c6a6..cfa9dc5 160000 --- a/deps/PawPaw +++ b/deps/PawPaw @@ -1 +1 @@ -Subproject commit 6a3c6a65a89abe221858c3f7635140074506bfc3 +Subproject commit cfa9dc50b32ebdb567d2d86467d3dc58157252c7 diff --git a/docs/LICENSES.md b/docs/LICENSES.md index 318f82d..a5eb242 100644 --- a/docs/LICENSES.md +++ b/docs/LICENSES.md @@ -34,6 +34,7 @@ Bellow follows a list of all code licenses used in Cardinal and linked submodule | cf | BSD-3-Clause | | | ChowDSP | GPL-3.0-or-later | | | dBiz | GPL-3.0-or-later | | +| DHE-Modules | MIT | | | DrumKit | CC0-1.0 | | | EnigmaCurry | GPL-3.0-or-later | | | E-Series | GPL-3.0-or-later | | @@ -160,6 +161,7 @@ Below is a list of artwork licenses from plugins | dBiz/* | CC-BY-NC-ND-4.0 | | | dBiz/DejaVuSansMono.ttf | Bitstream-Vera | | | dBiz/ShareTechMono-Regular.ttf | OFL-1.1 | | +| DHE-Modules/* | MIT | Same license as source code | | DrumKit/* | CC0-1.0 | | | DrumKit/component/NovaMono.ttf | OFL-1.1-RFN | | | EnigmaCurry/res/fonts/dseg/* | OFL-1.1-RFN | | diff --git a/dpf b/dpf index 6876fd0..1d5a31c 160000 --- a/dpf +++ b/dpf @@ -1 +1 @@ -Subproject commit 6876fd08ec9f0d1926158a4b60ed68ce9d33c6d4 +Subproject commit 1d5a31c1e2fec45b23e05543c646ae6092693914 diff --git a/include/helpers.hpp b/include/helpers.hpp index 8ffbe7f..ec23234 100644 --- a/include/helpers.hpp +++ b/include/helpers.hpp @@ -36,12 +36,6 @@ namespace rack { -#ifndef HEADLESS -namespace asset { -void updateForcingBlackSilverScrewMode(std::string slug); -} -#endif - struct CardinalPluginModelHelper : plugin::Model { virtual app::ModuleWidget* createModuleWidgetFromEngineLoad(engine::Module* m) = 0; virtual void removeCachedModuleWidget(engine::Module* m) = 0; @@ -78,9 +72,6 @@ struct CardinalPluginModel : CardinalPluginModelHelper } tm = dynamic_cast(m); } - #ifndef HEADLESS - asset::updateForcingBlackSilverScrewMode(slug); - #endif app::ModuleWidget* const tmw = new TModuleWidget(tm); DISTRHO_CUSTOM_SAFE_ASSERT_RETURN(m != nullptr ? m->model->name.c_str() : "null", tmw->module == m, nullptr); tmw->setModel(this); @@ -95,9 +86,6 @@ struct CardinalPluginModel : CardinalPluginModelHelper TModule* const tm = dynamic_cast(m); DISTRHO_SAFE_ASSERT_RETURN(tm != nullptr, nullptr); - #ifndef HEADLESS - asset::updateForcingBlackSilverScrewMode(slug); - #endif TModuleWidget* const tmw = new TModuleWidget(tm); DISTRHO_SAFE_ASSERT_RETURN(tmw->module == m, nullptr); tmw->setModel(this); diff --git a/include/settings.hpp b/include/settings.hpp index 49baef7..13b40e1 100644 --- a/include/settings.hpp +++ b/include/settings.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2022 Filipe Coelho + * Copyright (C) 2021-2023 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -22,8 +22,10 @@ namespace rack { namespace settings { -extern bool darkMode; extern int rateLimit; +// TODO remove after updating all plugins +extern bool darkMode; + } // namespace settings } // namespace rack diff --git a/include/simd-compat/emmintrin.h b/include/simd-compat/emmintrin.h index 1fc6dc0..3f8a42f 100644 --- a/include/simd-compat/emmintrin.h +++ b/include/simd-compat/emmintrin.h @@ -1,26 +1,19 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2023 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the LICENSE file. + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later */ #pragma once -#if (defined(__i386__) || defined(__x86_64__) || defined(__EMSCRIPTEN__)) && !defined(CARDINAL_NOSIMD) +#include "simd-compat.h" + +#if defined(CARDINAL_INCLUDING_IMMINTRIN_H) || defined(SIMDE_X86_SSE2_NATIVE) # include_next #else +# include "mmintrin.h" +# include "xmmintrin.h" # define SIMDE_ENABLE_NATIVE_ALIASES -# include "simde/x86/sse.h" +# include "simde/x86/sse2.h" # undef SIMDE_ENABLE_NATIVE_ALIASES #endif diff --git a/include/simd-compat/immintrin.h b/include/simd-compat/immintrin.h index 3490cb8..572a2b6 100644 --- a/include/simd-compat/immintrin.h +++ b/include/simd-compat/immintrin.h @@ -1,27 +1,24 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2023 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the LICENSE file. + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later */ #pragma once -#if (defined(__i386__) || defined(__x86_64__) || defined(__EMSCRIPTEN__)) && !defined(CARDINAL_NOSIMD) +#include "simd-compat.h" + +#if defined(CARDINAL_INCLUDING_EMULATED_IMMINTRIN_H) || defined(SIMDE_X86_SSE_NATIVE) +# define CARDINAL_INCLUDING_IMMINTRIN_H # include_next +# undef CARDINAL_INCLUDING_IMMINTRIN_H #else -# define SIMDE_ENABLE_NATIVE_ALIASES -# include "../simde/simde/x86/sse.h" -# include "../simde/simde/x86/sse2.h" -# undef SIMDE_ENABLE_NATIVE_ALIASES +# define CARDINAL_INCLUDING_EMULATED_IMMINTRIN_H +# include "mmintrin.h" +# include "xmmintrin.h" +# include "emmintrin.h" +# include "pmmintrin.h" +# include "tmmintrin.h" +# include "smmintrin.h" +# undef CARDINAL_INCLUDING_EMULATED_IMMINTRIN_H #endif diff --git a/include/simd-compat/mmintrin.h b/include/simd-compat/mmintrin.h index 3ca24af..e475090 100644 --- a/include/simd-compat/mmintrin.h +++ b/include/simd-compat/mmintrin.h @@ -1,28 +1,17 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2023 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the LICENSE file. + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later */ #pragma once -#if (defined(__i386__) || defined(__x86_64__)) && !defined(CARDINAL_NOSIMD) +#include "simd-compat.h" + +#if defined(CARDINAL_INCLUDING_IMMINTRIN_H) || defined(SIMDE_X86_MMX_NATIVE) # include_next -#elif defined(__EMSCRIPTEN__) && !defined(CARDINAL_NOSIMD) -# include #else # define SIMDE_ENABLE_NATIVE_ALIASES -# include "../simde/simde/x86/mmx.h" +# include "simde/x86/mmx.h" # undef SIMDE_ENABLE_NATIVE_ALIASES #endif diff --git a/include/simd-compat/pmmintrin.h b/include/simd-compat/pmmintrin.h index 8ba6b36..310fb4c 100644 --- a/include/simd-compat/pmmintrin.h +++ b/include/simd-compat/pmmintrin.h @@ -1,78 +1,20 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2023 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the LICENSE file. + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later */ #pragma once -#if (defined(__i386__) || defined(__x86_64__)) && !defined(CARDINAL_NOSIMD) -# include_next - -// bring in extra SSE3 support via simde -# define SIMDE_X86_SSE2_NATIVE -# define SIMDE_X86_SSE3_ENABLE_NATIVE_ALIASES - -// make sure to not include windows.h here -# ifdef _WIN32 -# define _WIN32_WAS_DEFINED -# undef _WIN32 -# endif - -// assume SSE3 only on macOS -# ifndef ARCH_MAC -# include "simde/x86/sse3.h" -# endif - -# ifdef _WIN32_WAS_DEFINED -# define _WIN32 -# undef _WIN32_WAS_DEFINED -# endif - -# undef SIMDE_X86_SSE2_NATIVE -# undef SIMDE_X86_SSE3_ENABLE_NATIVE_ALIASES +#include "simd-compat.h" -#elif defined(__EMSCRIPTEN__) && !defined(CARDINAL_NOSIMD) +#if defined(CARDINAL_INCLUDING_IMMINTRIN_H) || defined(SIMDE_X86_SSE3_NATIVE) # include_next - -static __inline__ __m64 __attribute__((__always_inline__, __nodebug__)) -_mm_set1_pi16(short w) -{ - return __extension__ (__m64){ static_cast(w), static_cast(w) }; -} - -/* -#elif defined(__ARM_NEON) -# include "../sse2neon/sse2neon.h" - -static inline -void __builtin_ia32_pause() -{ - __asm__ __volatile__("isb\n"); -} - -static inline -__m64 _mm_set1_pi16(short w) -{ - return vreinterpret_s64_s16(vdup_n_s16(w)); -} -*/ - #else +# include "mmintrin.h" +# include "xmmintrin.h" +# include "emmintrin.h" # define SIMDE_ENABLE_NATIVE_ALIASES -# include "simde/x86/sse.h" -# include "simde/x86/sse2.h" # include "simde/x86/sse3.h" # undef SIMDE_ENABLE_NATIVE_ALIASES #endif diff --git a/include/simd-compat/simd-compat.h b/include/simd-compat/simd-compat.h new file mode 100644 index 0000000..555db92 --- /dev/null +++ b/include/simd-compat/simd-compat.h @@ -0,0 +1,66 @@ +/* + * DISTRHO Cardinal Plugin + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +// native up to SSE3 +#if (defined(_M_X64) || defined(__amd64__) || defined(__SSE2__) || (defined(_M_IX86_FP) && _M_IX86_FP == 2)) && !defined(__EMSCRIPTEN__) && !defined(CARDINAL_NOSIMD) +# define SIMDE_X86_MMX_NATIVE +# define SIMDE_X86_SSE_NATIVE +# define SIMDE_X86_SSE2_NATIVE +# define SIMDE_X86_SSE3_NATIVE +#else +# define SIMDE_X86_MMX_NO_NATIVE +# define SIMDE_X86_SSE_NO_NATIVE +# define SIMDE_X86_SSE2_NO_NATIVE +# define SIMDE_X86_SSE3_NO_NATIVE +#endif + +// everything else is emulated +#define SIMDE_X86_SSSE3_NO_NATIVE +#define SIMDE_X86_SSE4_1_NO_NATIVE +#define SIMDE_X86_SSE4_2_NO_NATIVE +#define SIMDE_X86_XOP_NO_NATIVE +#define SIMDE_X86_AVX_NO_NATIVE +#define SIMDE_X86_AVX2_NO_NATIVE +#define SIMDE_X86_FMA_NO_NATIVE +#define SIMDE_X86_AVX512F_NO_NATIVE +#define SIMDE_X86_AVX512BF16_NO_NATIVE +#define SIMDE_X86_AVX512BW_NO_NATIVE +#define SIMDE_X86_AVX512VL_NO_NATIVE +#define SIMDE_X86_AVX512DQ_NO_NATIVE +#define SIMDE_X86_AVX512CD_NO_NATIVE +#define SIMDE_X86_AVX5124VNNIW_NO_NATIVE +#define SIMDE_X86_AVX512VNNI_NO_NATIVE +#define SIMDE_X86_AVX512VBMI2_NO_NATIVE +#define SIMDE_X86_AVX512VBMI_NO_NATIVE +#define SIMDE_X86_AVX512BITALG_NO_NATIVE +#define SIMDE_X86_AVX512VPOPCNTDQ_NO_NATIVE +#define SIMDE_X86_AVX512VP2INTERSECT_NO_NATIVE +#define SIMDE_X86_SVML_NO_NATIVE + +// control wasm simd state +#ifdef __EMSCRIPTEN__ +# ifdef CARDINAL_NOSIMD +# define SIMDE_WASM_SIMD128_NO_NATIVE +# else +# define SIMDE_WASM_SIMD128_NATIVE +# endif +#endif + +// fix win32 build +#ifdef _WIN32 +static inline +float simde_math_roundevenf(float v) { + float rounded = __builtin_roundf(v); + float diff = rounded - v; + if (__builtin_expect(!!(__builtin_fabsf(diff) == 0.5f) && ((int)rounded & 1), 0)) { + rounded = v - diff; + } + return rounded; +} +#define simde_math_roundevenf simde_math_roundevenf +#endif diff --git a/include/simd-compat/smmintrin.h b/include/simd-compat/smmintrin.h new file mode 100644 index 0000000..1bf8aa8 --- /dev/null +++ b/include/simd-compat/smmintrin.h @@ -0,0 +1,23 @@ +/* + * DISTRHO Cardinal Plugin + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include "simd-compat.h" + +#if defined(CARDINAL_INCLUDING_IMMINTRIN_H) || defined(SIMDE_X86_SSE4_1_NATIVE) +# include_next +#else +# include "mmintrin.h" +# include "xmmintrin.h" +# include "emmintrin.h" +# include "pmmintrin.h" +# include "tmmintrin.h" +# define SIMDE_ENABLE_NATIVE_ALIASES +# include "simde/x86/sse4.1.h" +# include "simde/x86/sse4.2.h" +# undef SIMDE_ENABLE_NATIVE_ALIASES +#endif diff --git a/include/simd-compat/tmmintrin.h b/include/simd-compat/tmmintrin.h new file mode 100644 index 0000000..b4a4ddd --- /dev/null +++ b/include/simd-compat/tmmintrin.h @@ -0,0 +1,21 @@ +/* + * DISTRHO Cardinal Plugin + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include "simd-compat.h" + +#if defined(CARDINAL_INCLUDING_IMMINTRIN_H) || defined(SIMDE_X86_SSSE3_NATIVE) +# include_next +#else +# include "mmintrin.h" +# include "xmmintrin.h" +# include "emmintrin.h" +# include "pmmintrin.h" +# define SIMDE_ENABLE_NATIVE_ALIASES +# include "simde/x86/ssse3.h" +# undef SIMDE_ENABLE_NATIVE_ALIASES +#endif diff --git a/include/simd-compat/xmmintrin.h b/include/simd-compat/xmmintrin.h index 3500893..3874baa 100644 --- a/include/simd-compat/xmmintrin.h +++ b/include/simd-compat/xmmintrin.h @@ -1,26 +1,20 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2023 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the LICENSE file. + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later */ #pragma once -#if (defined(__i386__) || defined(__x86_64__) || defined(__EMSCRIPTEN__)) && !defined(CARDINAL_NOSIMD) +#include "simd-compat.h" + +#if defined(CARDINAL_INCLUDING_IMMINTRIN_H) || defined(SIMDE_X86_SSE_NATIVE) # include_next #else +# include "mmintrin.h" # define SIMDE_ENABLE_NATIVE_ALIASES -# include "simde/x86/avx.h" +# include "simde/x86/sse.h" # undef SIMDE_ENABLE_NATIVE_ALIASES +// always use SSE2 mode, as seen in gcc +# include "emmintrin.h" #endif diff --git a/include/simd/Vector.hpp b/include/simd/Vector.hpp index 091af1b..96b1569 100644 --- a/include/simd/Vector.hpp +++ b/include/simd/Vector.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2022 Filipe Coelho + * Copyright (C) 2021-2023 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -17,7 +17,7 @@ /** * This file is an edited version of VCVRack's simd/Vector.hpp - * Copyright (C) 2016-2021 VCV. + * Copyright (C) 2016-2023 VCV. * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/include/simd/common.hpp b/include/simd/common.hpp new file mode 100644 index 0000000..11daad7 --- /dev/null +++ b/include/simd/common.hpp @@ -0,0 +1,16 @@ +/* + * DISTRHO Cardinal Plugin + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#define CARDINAL_INCLUDING_EMULATED_IMMINTRIN_H +#include "mmintrin.h" +#include "xmmintrin.h" +#include "emmintrin.h" +#include "pmmintrin.h" +#include "tmmintrin.h" +#include "smmintrin.h" +#undef CARDINAL_INCLUDING_EMULATED_IMMINTRIN_H diff --git a/include/simd/functions.hpp b/include/simd/functions.hpp new file mode 100644 index 0000000..4112df4 --- /dev/null +++ b/include/simd/functions.hpp @@ -0,0 +1,12 @@ +/* + * DISTRHO Cardinal Plugin + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include "simd/common.hpp" +#include_next "simd/functions.hpp" +// #undef SIMDE_MM_FROUND_NO_EXC +// #undef _MM_FROUND_NO_EXC diff --git a/jucewrapper/CMakeLists.txt b/jucewrapper/CMakeLists.txt index 6239e25..d3848e2 100644 --- a/jucewrapper/CMakeLists.txt +++ b/jucewrapper/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.15) -project(Cardinal VERSION 23.10) +project(Cardinal VERSION 24.01) include(FetchContent) FetchContent_Declare(JUCE diff --git a/plugins/Cardinal/src/HostTime.cpp b/plugins/Cardinal/src/HostTime.cpp index b920be4..f853379 100644 --- a/plugins/Cardinal/src/HostTime.cpp +++ b/plugins/Cardinal/src/HostTime.cpp @@ -214,10 +214,10 @@ struct HostTimeWidget : ModuleWidgetWith8HP { const float y = startY_cv + offset * padding; nvgBeginPath(vg); nvgRoundedRect(vg, startX - 1.0f, y - 2.f, box.size.x - startX * 2 + 2.f, 28.f, 4); - nvgFillColor(vg, rack::settings::darkMode ? nvgRGB(0xd0, 0xd0, 0xd0) : nvgRGB(0x2f, 0x2f, 0x2f)); + nvgFillColor(vg, rack::settings::preferDarkPanels ? nvgRGB(0xd0, 0xd0, 0xd0) : nvgRGB(0x2f, 0x2f, 0x2f)); nvgFill(vg); nvgBeginPath(vg); - nvgFillColor(vg, rack::settings::darkMode ? color::BLACK : color::WHITE); + nvgFillColor(vg, rack::settings::preferDarkPanels ? color::BLACK : color::WHITE); nvgText(vg, startX + 36, y + 16, text, nullptr); } diff --git a/plugins/Cardinal/src/ImGuiTextEditor.cpp b/plugins/Cardinal/src/ImGuiTextEditor.cpp index be713d5..7116ed8 100644 --- a/plugins/Cardinal/src/ImGuiTextEditor.cpp +++ b/plugins/Cardinal/src/ImGuiTextEditor.cpp @@ -234,11 +234,11 @@ void ImGuiTextEditor::onHoverScroll(const HoverScrollEvent& e) void ImGuiTextEditor::step() { - if (pData->darkMode != settings::darkMode) + if (pData->darkMode != settings::preferDarkPanels) { - pData->darkMode = settings::darkMode; - pData->editor.SetPalette(settings::darkMode ? TextEditor::GetDarkPalette() - : TextEditor::GetLightPalette()); + pData->darkMode = settings::preferDarkPanels; + pData->editor.SetPalette(settings::preferDarkPanels ? TextEditor::GetDarkPalette() + : TextEditor::GetLightPalette()); } ImGuiWidget::step(); diff --git a/plugins/Cardinal/src/ImGuiWidget.cpp b/plugins/Cardinal/src/ImGuiWidget.cpp index e0af702..de259e7 100644 --- a/plugins/Cardinal/src/ImGuiWidget.cpp +++ b/plugins/Cardinal/src/ImGuiWidget.cpp @@ -229,7 +229,7 @@ struct ImGuiWidget::PrivateData { colors[ImGuiCol_HeaderHovered] = color_DimCardinal; colors[ImGuiCol_HeaderActive] = color_Cardinal; - if (!settings::darkMode) + if (!settings::preferDarkPanels) { for (int c = 0; c < ImGuiCol_COUNT; ++c) { @@ -432,9 +432,9 @@ void ImGuiWidget::onSelectText(const SelectTextEvent& e) void ImGuiWidget::step() { - if (imData->darkMode != settings::darkMode) + if (imData->darkMode != settings::preferDarkPanels) { - imData->darkMode = settings::darkMode; + imData->darkMode = settings::preferDarkPanels; imData->resetEverything(true); } diff --git a/plugins/Cardinal/src/ModuleWidgets.hpp b/plugins/Cardinal/src/ModuleWidgets.hpp index 4cf46fe..3541cea 100644 --- a/plugins/Cardinal/src/ModuleWidgets.hpp +++ b/plugins/Cardinal/src/ModuleWidgets.hpp @@ -70,7 +70,7 @@ struct ModuleWidgetWithSideScrews : ModuleWidget { void drawBackground(NVGcontext* const vg) { nvgBeginPath(vg); nvgRect(vg, 0, 0, box.size.x, box.size.y); - if (rack::settings::darkMode) + if (rack::settings::preferDarkPanels) nvgFillPaint(vg, nvgLinearGradient(vg, 0, 0, 0, box.size.y, nvgRGB(0x18, 0x19, 0x19), nvgRGB(0x21, 0x22, 0x22))); else @@ -82,14 +82,14 @@ struct ModuleWidgetWithSideScrews : ModuleWidget { void drawOutputJacksArea(NVGcontext* const vg, const int numOutputs) { nvgBeginPath(vg); nvgRoundedRect(vg, startX_Out - 2.5f, startY - 2.0f, padding, padding * numOutputs, 4); - nvgFillColor(vg, rack::settings::darkMode ? nvgRGB(0xd0, 0xd0, 0xd0) : nvgRGB(0x2f, 0x2f, 0x2f)); + nvgFillColor(vg, rack::settings::preferDarkPanels ? nvgRGB(0xd0, 0xd0, 0xd0) : nvgRGB(0x2f, 0x2f, 0x2f)); nvgFill(vg); } void drawTextLine(NVGcontext* const vg, const uint posY, const char* const text) { const float y = startY + posY * padding; nvgBeginPath(vg); - nvgFillColor(vg, rack::settings::darkMode ? color::WHITE : color::BLACK); + nvgFillColor(vg, rack::settings::preferDarkPanels ? color::WHITE : color::BLACK); nvgText(vg, box.size.x * 0.5f, y + 16, text, nullptr); } diff --git a/plugins/Cardinal/src/SassyScope.cpp b/plugins/Cardinal/src/SassyScope.cpp index 8f866af..392fa2a 100644 --- a/plugins/Cardinal/src/SassyScope.cpp +++ b/plugins/Cardinal/src/SassyScope.cpp @@ -285,7 +285,7 @@ struct SassyScopeWidget : ImGuiWidget { ImGui::SetNextWindowSize(ImVec2(box.size.x * scaleFactor, box.size.y * scaleFactor)); ScopeData* const scope = module != nullptr ? &module->scope : getFakeScopeInstance(); - scope->darkMode = settings::darkMode; + scope->darkMode = settings::preferDarkPanels; do_show_scope_window(scope, scaleFactor); } diff --git a/plugins/Cardinal/src/TextEditor.cpp b/plugins/Cardinal/src/TextEditor.cpp index ba03cc1..e16e9a2 100644 --- a/plugins/Cardinal/src/TextEditor.cpp +++ b/plugins/Cardinal/src/TextEditor.cpp @@ -384,8 +384,8 @@ struct TextEditorModuleWidget : ModuleWidget { { nvgBeginPath(args.vg); nvgRect(args.vg, 0.0, 0.0, box.size.x, box.size.y); - nvgFillColor(args.vg, settings::darkMode ? nvgRGB(0x20, 0x20, 0x20) - : nvgRGB(0xe6, 0xe6, 0xe6)); + nvgFillColor(args.vg, settings::preferDarkPanels ? nvgRGB(0x20, 0x20, 0x20) + : nvgRGB(0xe6, 0xe6, 0xe6)); nvgFill(args.vg); ModuleWidget::draw(args); } diff --git a/plugins/Cardinal/src/Widgets.hpp b/plugins/Cardinal/src/Widgets.hpp index f836e58..6170112 100644 --- a/plugins/Cardinal/src/Widgets.hpp +++ b/plugins/Cardinal/src/Widgets.hpp @@ -231,7 +231,7 @@ struct NanoKnob : Knob { // bottom label (name) bndIconLabelValue(args.vg, -w, knobStartY + knobSize + BND_WIDGET_HEIGHT * 0.75f, w*3, BND_WIDGET_HEIGHT, -1, - settings::darkMode ? SCHEME_WHITE : SCHEME_BLACK, BND_CENTER, + settings::preferDarkPanels ? SCHEME_WHITE : SCHEME_BLACK, BND_CENTER, BND_LABEL_FONT_SIZE, displayLabel.c_str(), nullptr); } diff --git a/plugins/DHE-Modules b/plugins/DHE-Modules new file mode 160000 index 0000000..1d1c286 --- /dev/null +++ b/plugins/DHE-Modules @@ -0,0 +1 @@ +Subproject commit 1d1c286fc69babdb36dfe5fa4fe2856b0f707854 diff --git a/plugins/GlueTheGiant b/plugins/GlueTheGiant index 5f05d62..7e20713 160000 --- a/plugins/GlueTheGiant +++ b/plugins/GlueTheGiant @@ -1 +1 @@ -Subproject commit 5f05d62ddc2773098daf1044eb6698581acd4eb6 +Subproject commit 7e20713eacc51179cd7faf0f4428def2b82273a9 diff --git a/plugins/ImpromptuModularDark/PanelTheme.cpp b/plugins/ImpromptuModularDark/PanelTheme.cpp index 6106d31..c8f3dae 100644 --- a/plugins/ImpromptuModularDark/PanelTheme.cpp +++ b/plugins/ImpromptuModularDark/PanelTheme.cpp @@ -17,12 +17,12 @@ void writeThemeAndContrastAsDefault() {} void saveThemeAndContrastAsDefault(int, float) {} void loadThemeAndContrastFromDefault(int* panelTheme, float* panelContrast) { - *panelTheme = rack::settings::darkMode ? 1 : 0; + *panelTheme = rack::settings::preferDarkPanels ? 1 : 0; *panelContrast = panelContrastDefault; } bool isDark(int*) { - return rack::settings::darkMode; + return rack::settings::preferDarkPanels; } void readThemeAndContrastFromDefault() {} @@ -47,7 +47,7 @@ void PanelBaseWidget::draw(const DrawArgs& args) { void InverterWidget::draw(const DrawArgs& args) { TransparentWidget::draw(args); - if (rack::settings::darkMode) { + if (rack::settings::preferDarkPanels) { // nvgSave(args.vg); nvgBeginPath(args.vg); nvgFillColor(args.vg, SCHEME_WHITE);// this is the source, the current framebuffer is the dest diff --git a/plugins/Makefile b/plugins/Makefile index 4862e5f..df8c088 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -284,7 +284,6 @@ endif ifeq ($(shell $(PKG_CONFIG) --exists fftw3f && echo true),true) PLUGIN_FILES += Cardinal/src/AudioToCVPitch.cpp # MINIPLUGIN_FILES += Cardinal/src/AudioToCVPitch.cpp -BASE_FLAGS += -DHAVE_FFTW3F endif # -------------------------------------------------------------- @@ -656,6 +655,11 @@ PLUGIN_FILES += $(filter-out dBiz/src/plugin.cpp,$(wildcard dBiz/src/*.cpp)) DBIZ_CUSTOM = Chord DarkDefaultItem Divider FourSeq FourSeqWidget OrangeLight VCA4 Wavefolder darkPanelID lightPanelID DBIZ_CUSTOM_PER_FILE = LERP MultiFilter Oscillator calcOutput sineOsc subBank +# -------------------------------------------------------------- +# DHE-Modules + +PLUGIN_FILES += $(filter-out DHE-Modules/src/plugin.cpp,$(wildcard DHE-Modules/src/modules/*/init.cpp)) + # -------------------------------------------------------------- # DrumKit @@ -1043,7 +1047,7 @@ SURGEXT_FLAGS += $(NOFINITE_FLAGS) SURGEXT_FLAGS += -std=gnu++17 SURGEXT_FLAGS += -DTIXML_USE_STL=1 SURGEXT_FLAGS += \ - -Isurgext/libs/sst/sst-basic-blocks/include \ + -Isurgext/libs/sst-rackhelpers/include \ -Isurgext/surge/src/common \ -Isurgext/surge/src/common/dsp \ -Isurgext/surge/src/common/dsp/filters \ @@ -1052,20 +1056,20 @@ SURGEXT_FLAGS += \ -Isurgext/surge/src/common/dsp/oscillators \ -Isurgext/surge/src/common/dsp/modulators \ -Isurgext/surge/src/surge-testrunner \ - -Isurgext/surge/libs/sst/sst-filters/include \ + -Isurgext/surge/libs/fmt/include \ + -Isurgext/surge/libs/LuaJitLib/LuaJIT/src \ + -Isurgext/surge/libs/sst/sst-basic-blocks/include \ -Isurgext/surge/libs/sst/sst-cpputils/include \ - -Isurgext/surge/libs/sst/sst-waveshapers/include \ + -Isurgext/surge/libs/sst/sst-effects/include \ + -Isurgext/surge/libs/sst/sst-filters/include \ -Isurgext/surge/libs/sst/sst-plugininfra/include \ -Isurgext/surge/libs/sst/sst-plugininfra/libs/tinyxml/include \ -Isurgext/surge/libs/sst/sst-plugininfra/libs/filesystem \ - -Isurgext/surge/libs/fmt/include \ - -Isurgext/surge/libs/LuaJitLib/LuaJIT/src \ + -Isurgext/surge/libs/sst/sst-waveshapers/include \ -Isurgext/surge/libs/strnatcmp \ -Isurgext/surge/src/headless \ -Isurgext/surge/libs/tuning-library/include \ -I../deps/surge-build/libs/sst/sst-plugininfra/libs/filesystem/include \ - -include limits \ - -include cstdint \ -DSURGE_COMPILE_BLOCK_SIZE=8 \ -DSURGE_SKIP_ODDSOUND_MTS \ -DHAS_LUA=0 \ @@ -1296,6 +1300,14 @@ BASE_FLAGS += -D'aligned_alloc_16(ptr)'='aligned_alloc(16,ptr)' BASE_FLAGS += -D'aligned_free_16(ptr)'='free(ptr)' endif +ifeq ($(WASM),true) +BASE_FLAGS += -DEIGEN_DONT_VECTORIZE=1 +endif + +ifeq ($(shell $(PKG_CONFIG) --exists fftw3f && echo true),true) +BASE_FLAGS += -DHAVE_FFTW3F +endif + ifeq ($(shell $(PKG_CONFIG) --exists sndfile && echo true),true) BASE_FLAGS += -DHAVE_SNDFILE endif @@ -1345,10 +1357,6 @@ RTNEURAL_FLAGS += -DSKIP_MINGW_FORMAT RTNEURAL_FLAGS += -DRTNEURAL_DEFAULT_ALIGNMENT=16 RTNEURAL_FLAGS += -DRTNEURAL_USE_EIGEN=1 -ifeq ($(WASM),true) -RTNEURAL_FLAGS += -DEIGEN_DONT_VECTORIZE=1 -endif - RTNEURAL_FLAGS += -ICardinal/src/AIDA-X/RTNeural RTNEURAL_FLAGS += -ICardinal/src/AIDA-X/RTNeural/modules/Eigen @@ -1403,6 +1411,7 @@ RESOURCE_FILES += BaconPlugs/res/midi/chopin RESOURCE_FILES += BaconPlugs/res/midi/debussy RESOURCE_FILES += BaconPlugs/res/midi/goldberg RESOURCE_FILES += cf/playeroscs +RESOURCE_FILES += DHE-Modules/svg RESOURCE_FILES += DrumKit/res/samples RESOURCE_FILES += MindMeldModular/res/ShapeMaster/CommunityPresets RESOURCE_FILES += MindMeldModular/res/ShapeMaster/CommunityShapes @@ -1416,7 +1425,6 @@ RESOURCE_FILES += surgext/build/surge-data/configuration.xml RESOURCE_FILES += surgext/build/surge-data/fx_presets RESOURCE_FILES += surgext/build/surge-data/wavetables RESOURCE_FILES += surgext/build/surge-data/windows.wt -RESOURCE_FILES += surgext/patches RESOURCE_FILES += $(wildcard surgext/res/xt/fonts/quicksand/*.ttf) RESOURCE_FILES += $(wildcard unless_modules/art/*.art) RESOURCE_FILES += $(wildcard unless_modules/art/svg/*/*.svg) @@ -2230,6 +2238,14 @@ $(BUILD_DIR)/dBiz/src/%.cpp.o: dBiz/src/%.cpp $(foreach m,$(DBIZ_CUSTOM_PER_FILE),$(call custom_per_file_names,$(m),dBiz_$(shell basename $*))) \ -DpluginInstance=pluginInstance__dBiz +$(BUILD_DIR)/DHE-Modules/src/%.cpp.o: DHE-Modules/src/%.cpp + -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" + @echo "Compiling $<" + $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ \ + $(foreach m,$(DHE_CUSTOM),$(call custom_module_names,$(m),DHE)) \ + -DpluginInstance=pluginInstance__DHE \ + -IDHE-Modules/src + $(BUILD_DIR)/DrumKit/%.cpp.o: DrumKit/%.cpp -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" @echo "Compiling $<" diff --git a/plugins/RebelTech b/plugins/RebelTech index 6ac79f5..2d06199 160000 --- a/plugins/RebelTech +++ b/plugins/RebelTech @@ -1 +1 @@ -Subproject commit 6ac79f59c5b95433d82bcc759c4cd0642ec35098 +Subproject commit 2d06199dd36ecdfe33d640ed1602f1041930f013 diff --git a/plugins/Sapphire b/plugins/Sapphire index 2d374e2..9d9d3ae 160000 --- a/plugins/Sapphire +++ b/plugins/Sapphire @@ -1 +1 @@ -Subproject commit 2d374e2222475aa4207aec8c541716ed467e2619 +Subproject commit 9d9d3ae703259b55a2734e03a9421874ebd35cf9 diff --git a/plugins/plugins-mini.cpp b/plugins/plugins-mini.cpp index 38fdb17..c6f45f8 100644 --- a/plugins/plugins-mini.cpp +++ b/plugins/plugins-mini.cpp @@ -353,7 +353,7 @@ static void initStatic__BogaudioModules() { // Make sure to use match Cardinal theme Skins& skins(Skins::skins()); - skins._default = settings::darkMode ? "dark" : "light"; + skins._default = settings::preferDarkPanels ? "dark" : "light"; p->addModel(modelAD); p->addModel(modelBogaudioLFO); @@ -559,28 +559,34 @@ static void initStatic__surgext() // Add the ported ones p->addModel(modelSurgeLFO); p->addModel(modelSurgeMixer); + p->addModel(modelSurgeMixerSlider); p->addModel(modelSurgeModMatrix); p->addModel(modelSurgeWaveshaper); /* p->addModel(modelSurgeDelay); p->addModel(modelSurgeDelayLineByFreq); p->addModel(modelSurgeDelayLineByFreqExpanded); + p->addModel(modelSurgeDigitalRingMods); p->addModel(modelSurgeVCF); */ spl.removeModule("SurgeXTDelay"); spl.removeModule("SurgeXTDelayLineByFreq"); spl.removeModule("SurgeXTDelayLineByFreqExpanded"); + spl.removeModule("SurgeXTDigitalRingMod"); spl.removeModule("SurgeXTVCF"); + spl.removeModule("SurgeXTFXBonsai"); spl.removeModule("SurgeXTFXChorus"); spl.removeModule("SurgeXTFXChow"); spl.removeModule("SurgeXTFXCombulator"); + spl.removeModule("SurgeXTDigitalRingMod"); spl.removeModule("SurgeXTFXDistortion"); spl.removeModule("SurgeXTFXExciter"); spl.removeModule("SurgeXTFXEnsemble"); spl.removeModule("SurgeXTFXFlanger"); spl.removeModule("SurgeXTFXFrequencyShifter"); spl.removeModule("SurgeXTFXNeuron"); + spl.removeModule("SurgeXTFXNimbus"); spl.removeModule("SurgeXTFXPhaser"); spl.removeModule("SurgeXTFXResonator"); spl.removeModule("SurgeXTFXReverb"); @@ -595,10 +601,14 @@ static void initStatic__surgext() p->addModel(modelEGxVCA); p->addModel(modelQuadAD); p->addModel(modelQuadLFO); + p->addModel(modelUnisonHelper); + p->addModel(modelUnisonHelperCVExpander); */ spl.removeModule("SurgeXTEGxVCA"); spl.removeModule("SurgeXTQuadAD"); spl.removeModule("SurgeXTQuadLFO"); + spl.removeModule("SurgeXTUnisonHelper"); + spl.removeModule("SurgeXTUnisonHelperCVExpander"); surgext_rack_initialize(); } @@ -649,7 +659,7 @@ void destroyStaticPlugins() void updateStaticPluginsDarkMode() { - const bool darkMode = settings::darkMode; + const bool darkMode = settings::preferDarkPanels; // bogaudio { Skins& skins(Skins::skins()); diff --git a/plugins/plugins.cpp b/plugins/plugins.cpp index 13127cd..6051cdd 100644 --- a/plugins/plugins.cpp +++ b/plugins/plugins.cpp @@ -1,18 +1,7 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2022 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the LICENSE file. + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later */ #include "rack.hpp" @@ -29,7 +18,6 @@ // ZamAudio (always enabled) - TODO // #include "ZamAudio/src/plugin.hpp" -#ifndef NOPLUGINS // 21kHz #include "21kHz/src/21kHz.hpp" @@ -335,6 +323,26 @@ extern Model* modelTestVCF; #undef modelFourSeq #undef modelVCA4 +// DHEModules +// NOTE very unique way of handling init, needs special handling +namespace dhe { +namespace blossom { void init(Plugin*); } +namespace buttons { void init(Plugin*); } +namespace cubic { void init(Plugin*); } +namespace curve_sequencer { void init(Plugin*); } +namespace envelope { void init(Plugin*); } +namespace func { void init(Plugin*); } +namespace fuzzy_logic { void init(Plugin*); } +namespace gator { void init(Plugin*); } +namespace ranger { void init(Plugin*); } +namespace scannibal { void init(Plugin*); } +namespace sequencizer { void init(Plugin*); } +namespace swave { void init(Plugin*); } +namespace tapers { void init(Plugin*); } +namespace truth { void init(Plugin*); } +namespace xycloid { void init(Plugin*); } +} + // DrumKit #include "DrumKit/src/DrumKit.hpp" void setupSamples(); @@ -785,16 +793,13 @@ void surgext_rack_update_theme(); #include "ZZC/src/ZZC.hpp" #undef modelClock -#endif // NOPLUGINS - // known terminal modules std::vector hostTerminalModels; -#ifndef NOPLUGINS // stuff that reads config files, we don't want that int loadConsoleType() { return 0; } -bool loadDarkAsDefault() { return settings::darkMode; } -ModuleTheme loadDefaultTheme() { return settings::darkMode ? DARK_THEME : LIGHT_THEME; } +bool loadDarkAsDefault() { return settings::preferDarkPanels; } +ModuleTheme loadDefaultTheme() { return settings::preferDarkPanels ? DARK_THEME : LIGHT_THEME; } int loadDirectOutMode() { return 0; } void readDefaultTheme() { defaultPanelTheme = loadDefaultTheme(); } void saveConsoleType(int) {} @@ -803,13 +808,11 @@ void saveDefaultTheme(ModuleTheme) {} void saveDirectOutMode(bool) {} void saveHighQualityAsDefault(bool) {} void writeDefaultTheme() {} -#endif // plugin instances Plugin* pluginInstance__Cardinal; Plugin* pluginInstance__Fundamental; // Plugin* pluginInstance__ZamAudio; -#ifndef NOPLUGINS Plugin* pluginInstance__21kHz; Plugin* pluginInstance__8Mode; extern Plugin* pluginInstance__AaronStatic; @@ -831,6 +834,7 @@ Plugin* pluginInstance__CatroModulo; Plugin* pluginInstance__cf; Plugin* pluginInstance__ChowDSP; Plugin* pluginInstance__dBiz; +Plugin* pluginInstance__DHE; extern Plugin* pluginInstance__DrumKit; Plugin* pluginInstance__EnigmaCurry; Plugin* pluginInstance__ESeries; @@ -882,7 +886,6 @@ Plugin* pluginInstance__Voxglitch; Plugin* pluginInstance__WhatTheRack; Plugin* pluginInstance__ZetaCarinaeModules; Plugin* pluginInstance__ZZC; -#endif // NOPLUGINS namespace rack { @@ -1104,7 +1107,6 @@ static void initStatic__ZamAudio() } */ -#ifndef NOPLUGINS static void initStatic__21kHz() { Plugin* const p = new Plugin; @@ -1569,7 +1571,7 @@ static void initStatic__BogaudioModules() { // Make sure to use dark theme as default Skins& skins(Skins::skins()); - skins._default = settings::darkMode ? "dark" : "light"; + skins._default = settings::preferDarkPanels ? "dark" : "light"; #define modelADSR modelBogaudioADSR #define modelLFO modelBogaudioLFO #define modelNoise modelBogaudioNoise @@ -1846,6 +1848,32 @@ static void initStatic__dBiz() } } +static void initStatic__DHE() +{ + Plugin* const p = new Plugin; + pluginInstance__DHE = p; + + const StaticPluginLoader spl(p, "DHE-Modules"); + if (spl.ok()) + { + dhe::blossom::init(p); + dhe::buttons::init(p); + dhe::cubic::init(p); + dhe::curve_sequencer::init(p); + dhe::envelope::init(p); + dhe::func::init(p); + dhe::fuzzy_logic::init(p); + dhe::gator::init(p); + dhe::ranger::init(p); + dhe::scannibal::init(p); + dhe::sequencizer::init(p); + dhe::swave::init(p); + dhe::tapers::init(p); + dhe::truth::init(p); + dhe::xycloid::init(p); + } +} + static void initStatic__DrumKit() { Plugin* const p = new Plugin; @@ -2780,7 +2808,11 @@ static void initStatic__Sapphire() if (spl.ok()) { p->addModel(modelElastika); + p->addModel(modelFrolic); + p->addModel(modelGlee); p->addModel(modelMoots); + p->addModel(modelTin); + p->addModel(modelTricorder); p->addModel(modelTubeUnit); } } @@ -2954,9 +2986,11 @@ static void initStatic__surgext() p->addModel(modelSurgeDelay); p->addModel(modelSurgeDelayLineByFreq); p->addModel(modelSurgeDelayLineByFreqExpanded); + p->addModel(modelSurgeDigitalRingMods); p->addModel(modelSurgeWaveshaper); p->addModel(modelSurgeLFO); p->addModel(modelSurgeMixer); + p->addModel(modelSurgeMixerSlider); p->addModel(modelSurgeModMatrix); p->addModel(modelFXReverb); @@ -2975,12 +3009,16 @@ static void initStatic__surgext() p->addModel(modelFXExciter); p->addModel(modelFXEnsemble); p->addModel(modelFXCombulator); + p->addModel(modelFXNimbus); p->addModel(modelFXSpringReverb); p->addModel(modelFXTreeMonster); + p->addModel(modelFXBonsai); p->addModel(modelEGxVCA); p->addModel(modelQuadAD); p->addModel(modelQuadLFO); + p->addModel(modelUnisonHelper); + p->addModel(modelUnisonHelperCVExpander); surgext_rack_initialize(); } @@ -3115,14 +3153,12 @@ static void initStatic__ZZC() #undef modelClock } } -#endif // NOPLUGINS void initStaticPlugins() { initStatic__Cardinal(); initStatic__Fundamental(); // initStatic__ZamAudio(); -#ifndef NOPLUGINS initStatic__21kHz(); initStatic__8Mode(); initStatic__AaronStatic(); @@ -3144,6 +3180,7 @@ void initStaticPlugins() initStatic__cf(); initStatic__ChowDSP(); initStatic__dBiz(); + initStatic__DHE(); initStatic__DrumKit(); initStatic__EnigmaCurry(); initStatic__ESeries(); @@ -3195,7 +3232,6 @@ void initStaticPlugins() initStatic__WhatTheRack(); initStatic__ZetaCarinaeModules(); initStatic__ZZC(); -#endif // NOPLUGINS } void destroyStaticPlugins() @@ -3207,8 +3243,7 @@ void destroyStaticPlugins() void updateStaticPluginsDarkMode() { -#ifndef NOPLUGINS - const bool darkMode = settings::darkMode; + const bool darkMode = settings::preferDarkPanels; // bogaudio { Skins& skins(Skins::skins()); @@ -3231,7 +3266,6 @@ void updateStaticPluginsDarkMode() { surgext_rack_update_theme(); } -#endif } } diff --git a/plugins/surgext b/plugins/surgext index f4420b1..183a505 160000 --- a/plugins/surgext +++ b/plugins/surgext @@ -1 +1 @@ -Subproject commit f4420b19c7137d85c0390ef494bb880cc2726e74 +Subproject commit 183a50590aa587ec4e4a6a35f857f63a25ab86ff diff --git a/plugins/surgext-helper/surgext-helper.cpp b/plugins/surgext-helper/surgext-helper.cpp index c349e87..059ea54 100644 --- a/plugins/surgext-helper/surgext-helper.cpp +++ b/plugins/surgext-helper/surgext-helper.cpp @@ -1,18 +1,7 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2022 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the LICENSE file. + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later */ #include "../BaconPlugs/src/Style.hpp" @@ -23,15 +12,16 @@ using namespace sst::surgext_rack::style; void surgext_rack_initialize() { - BaconStyle::get()->activeStyle = rack::settings::darkMode ? BaconStyle::DARK : BaconStyle::LIGHT; + BaconStyle::get()->activeStyle = rack::settings::preferDarkPanels ? BaconStyle::DARK : BaconStyle::LIGHT; XTStyle::initialize(); + XTStyle::setGlobalStyle(rack::settings::preferDarkPanels ? XTStyle::Style::DARK : XTStyle::Style::LIGHT); } void surgext_rack_update_theme() { - BaconStyle::get()->activeStyle = rack::settings::darkMode ? BaconStyle::DARK : BaconStyle::LIGHT; + BaconStyle::get()->activeStyle = rack::settings::preferDarkPanels ? BaconStyle::DARK : BaconStyle::LIGHT; BaconStyle::get()->notifyStyleListeners(); - XTStyle::setGlobalStyle(rack::settings::darkMode ? XTStyle::Style::DARK : XTStyle::Style::LIGHT); + XTStyle::setGlobalStyle(rack::settings::preferDarkPanels ? XTStyle::Style::DARK : XTStyle::Style::LIGHT); XTStyle::notifyStyleListeners(); } diff --git a/plugins/unless_modules b/plugins/unless_modules index b91d953..0106e45 160000 --- a/plugins/unless_modules +++ b/plugins/unless_modules @@ -1 +1 @@ -Subproject commit b91d953ba545dd92220efd91f922759f18425c56 +Subproject commit 0106e455400a9e8bf3bbbb0abde4418e7614c5aa diff --git a/src/CardinalCommon.cpp b/src/CardinalCommon.cpp index 8fdba7e..266a0fc 100644 --- a/src/CardinalCommon.cpp +++ b/src/CardinalCommon.cpp @@ -1,18 +1,7 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2023 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the LICENSE file. + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later */ /** @@ -110,7 +99,7 @@ void destroyStaticPlugins(); } } -const std::string CARDINAL_VERSION = "23.10"; +const std::string CARDINAL_VERSION = "24.01"; START_NAMESPACE_DISTRHO @@ -410,7 +399,7 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB settings::browserZoom = -1.f; settings::invertZoom = false; settings::squeezeModules = true; - settings::darkMode = true; + settings::preferDarkPanels = true; settings::uiTheme = "dark"; // runtime behaviour diff --git a/src/CardinalPlugin.cpp b/src/CardinalPlugin.cpp index 9e7414b..92c44ac 100644 --- a/src/CardinalPlugin.cpp +++ b/src/CardinalPlugin.cpp @@ -1,18 +1,7 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2023 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the LICENSE file. + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later */ #include @@ -417,7 +406,7 @@ protected: uint32_t getVersion() const override { - return d_version(0, 23, 10); + return d_version(0, 24, 1); } int64_t getUniqueId() const override diff --git a/src/Makefile.cardinal.mk b/src/Makefile.cardinal.mk index 31b3b4c..e5271dd 100644 --- a/src/Makefile.cardinal.mk +++ b/src/Makefile.cardinal.mk @@ -330,8 +330,6 @@ SYMLINKED_DIRS_RESOURCES += Orbits/presets SYMLINKED_DIRS_RESOURCES += stoermelder-packone/presets SYMLINKED_DIRS_RESOURCES += surgext/build/surge-data/fx_presets SYMLINKED_DIRS_RESOURCES += surgext/build/surge-data/wavetables -SYMLINKED_DIRS_RESOURCES += surgext/patches -SYMLINKED_DIRS_RESOURCES += surgext/presets endif LINK_FLAGS += $(foreach d,$(SYMLINKED_DIRS_RESOURCES),--preload-file=../../bin/CardinalNative.lv2/resources/$(d)@/resources/$(d)) diff --git a/src/Rack b/src/Rack index f1576e2..8c6f41b 160000 --- a/src/Rack +++ b/src/Rack @@ -1 +1 @@ -Subproject commit f1576e2bb870da297789300117accb9d5fe44c5e +Subproject commit 8c6f41b778b4bf8860b89b36d5503fd37924077f diff --git a/src/custom/asset.cpp b/src/custom/asset.cpp index c1a2897..f78ea68 100644 --- a/src/custom/asset.cpp +++ b/src/custom/asset.cpp @@ -31,11 +31,6 @@ namespace rack { namespace asset { -#ifndef HEADLESS -extern bool forceBlackScrew; -extern bool forceSilverScrew; -#endif - std::string configDir; // points to writable config dir (might be equal to userDir) std::string userDir; // points to common writable dir std::string systemDir; // points to plugin resources dir (or installed/local Rack dir) @@ -59,12 +54,6 @@ static inline std::string& trim(std::string& s) // get system resource, trimming "res/" prefix if we are loaded as a plugin bundle std::string system(std::string filename) { - #ifndef HEADLESS - /**/ if (forceBlackScrew && string::endsWith(filename, "/ScrewBlack.svg")) - filename = filename.substr(0, filename.size()-15) + "/./ScrewBlack.svg"; - else if (forceSilverScrew && string::endsWith(filename, "/ScrewSilver.svg")) - filename = filename.substr(0, filename.size()-16) + "/./ScrewSilver.svg"; - #endif return system::join(systemDir, bundlePath.empty() ? filename : trim(filename)); } diff --git a/src/custom/dep.cpp b/src/custom/dep.cpp index 18d6df4..a7fd1e2 100644 --- a/src/custom/dep.cpp +++ b/src/custom/dep.cpp @@ -1,18 +1,7 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2022 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the LICENSE file. + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later */ #define STDIO_OVERRIDE Rackdep @@ -23,51 +12,14 @@ #include namespace rack { -#ifndef HEADLESS -namespace asset { -bool forceBlackScrew = false; -bool forceSilverScrew = false; -void updateForcingBlackSilverScrewMode(std::string slug) { - forceBlackScrew = ( - // arable instruments - slug == "Joni" - // axioma - || slug == "TheBifurcator" - || slug == "Tesseract" - || slug == "Ikeda" - || slug == "Rhodonea" - // parable instruments - || slug == "Neil" - // rackwindows - || slug == "bitshiftgain" - || slug == "capacitor" - || slug == "capacitor_stereo" - || slug == "chorus" - || slug == "console" - || slug == "console_mm" - || slug == "distance" - || slug == "golem" - || slug == "holt" - || slug == "hombre" - || slug == "interstage" - || slug == "monitoring" - || slug == "mv" - || slug == "rasp" - || slug == "reseq" - || slug == "tape" - || slug == "tremolo" - || slug == "vibrato" - ); -} -} -#endif namespace plugin { void updateStaticPluginsDarkMode(); } namespace settings { -bool darkMode = true; int rateLimit = 0; +extern bool preferDarkPanels; extern std::string uiTheme; +bool darkMode; // TODO remove after updating all plugins } namespace ui { void refreshTheme(); @@ -90,7 +42,7 @@ float FollowerBase::efGainMaxDecibelsDebug = 12.0f; extern "C" { NVGcolor nvgRGBblank(const unsigned char r, const unsigned char g, const unsigned char b) { - return rack::settings::darkMode ? nvgRGB(0x20, 0x20, 0x20) : nvgRGB(r, g, b); + return rack::settings::preferDarkPanels ? nvgRGB(0x20, 0x20, 0x20) : nvgRGB(r, g, b); } } @@ -111,6 +63,7 @@ enum DarkMode { kModeAudibleInstruments, kModeBidoo, kModeCf, + kModeDHE, kModeDrumKit, kModeESeries, kModeHetrickCV, @@ -263,6 +216,35 @@ static const struct { { kModeCf, "/cf/res/SUB.svg", {}, -1 }, { kModeCf, "/cf/res/trSEQ.svg", {}, -1 }, { kModeCf, "/cf/res/VARIABLE.svg", {}, -1 }, + // MIT + { kModeDHE, "/DHE-Modules/svg/blossom.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/booster-stage.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/buttons.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/cubic.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/curve-sequencer-4.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/curve-sequencer-8.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/curve-sequencer-16.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/func.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/func-6.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/fuzzy-logic-h.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/fuzzy-logic-z.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/gator.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/hostage.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/ranger.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/scannibal-4.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/scannibal-8.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/scannibal-16.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/sequencizer-4.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/sequencizer-8.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/sequencizer-16.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/stage.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/swave.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/tapers.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/truth-2.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/truth-3.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/truth-4.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/upstage.svg", {}, -1 }, + { kModeDHE, "/DHE-Modules/svg/xycloid.svg", {}, -1 }, // CC0-1.0 { kModeDrumKit, "/DrumKit/res/Baronial.svg", {}, -1 }, { kModeDrumKit, "/DrumKit/res/BD9.svg", {}, -1 }, @@ -648,6 +630,24 @@ static const struct { { kModeSonusmodular, "/sonusmodular/res/yabp.svg" }, }; +static inline +unsigned int darkerColor(const unsigned int color) noexcept +{ + return (color & 0xff000000) + | (std::max(0, ((color & 0xff0000) >> 16) - 0x80) << 16) + | (std::max(0, ((color & 0xff00) >> 8) - 0x80) << 8) + | (std::max(0, (color & 0xff) - 0x80)); +} + +static inline +unsigned int lighterColor(const unsigned int color) noexcept +{ + return (color & 0xff000000) + | (std::min(0xff, ((color & 0xff0000) >> 16) + 0x80) << 16) + | (std::min(0xff, ((color & 0xff00) >> 8) + 0x80) << 8) + | (std::min(0xff, (color & 0xff) + 0x80)); +} + static inline unsigned int invertColor(const unsigned int color) noexcept { @@ -707,6 +707,10 @@ bool invertPaintForDarkMode(const DarkMode mode, NSVGshape* const shape, NSVGpai } } break; + // Special case for DHE, mark things darker instead of inverting + case kModeDHE: + paint.color = darkerColor(paint.color); + return true; // Special case for JW-Modules colors case kModeJW: switch (paint.color) @@ -1444,7 +1448,7 @@ postparse: const ExtendedNSVGimage ext = { handle, handleOrig, handleMOD, shapesOrig, shapesMOD }; loadedDarkSVGs.push_back(ext); - if (rack::settings::darkMode) + if (rack::settings::preferDarkPanels) { if (shapesMOD != nullptr) handle->shapes = shapesMOD; @@ -1458,7 +1462,7 @@ postparse: const ExtendedNSVGimage ext = { handle, handleOrig, handleMOD, shapesOrig, shapesMOD }; loadedLightSVGs.push_back(ext); - if (!rack::settings::darkMode) + if (!rack::settings::preferDarkPanels) { if (shapesMOD != nullptr) handle->shapes = shapesMOD; @@ -1510,10 +1514,8 @@ namespace rack { void switchDarkMode(const bool darkMode) { #ifndef HEADLESS - if (settings::darkMode == darkMode) - return; - - settings::darkMode = darkMode; + settings::darkMode = darkMode; // TODO remove after updating all plugins + settings::preferDarkPanels = darkMode; settings::uiTheme = darkMode ? "dark" : "light"; ui::refreshTheme(); plugin::updateStaticPluginsDarkMode(); diff --git a/src/override/MenuBar.cpp b/src/override/MenuBar.cpp index c4464be..e68abf8 100644 --- a/src/override/MenuBar.cpp +++ b/src/override/MenuBar.cpp @@ -625,10 +625,10 @@ struct ViewButton : MenuButton { #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS std::string darkModeText; - if (settings::darkMode) + if (settings::preferDarkPanels) darkModeText = CHECKMARK_STRING; menu->addChild(createMenuItem("Dark Mode", darkModeText, []() { - switchDarkMode(!settings::darkMode); + switchDarkMode(!settings::preferDarkPanels); setAllFramebufferWidgetsDirty(APP->scene); })); #endif diff --git a/src/override/common.cpp b/src/override/common.cpp index 336034b..acf6a56 100644 --- a/src/override/common.cpp +++ b/src/override/common.cpp @@ -1,18 +1,7 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2023 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the LICENSE file. + * Copyright (C) 2021-2024 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later */ /** @@ -63,7 +52,7 @@ const std::string APP_NAME = "Cardinal"; const std::string APP_EDITION = getPluginFormatName(); const std::string APP_EDITION_NAME = "Audio Plugin"; const std::string APP_VERSION_MAJOR = "2"; -const std::string APP_VERSION = "2.3.0"; +const std::string APP_VERSION = "2.4.1"; #if defined ARCH_WIN const std::string APP_OS = "win"; #elif defined ARCH_MAC diff --git a/src/override/diffs/Engine.cpp.diff b/src/override/diffs/Engine.cpp.diff index df12535..c756ebf 100644 --- a/src/override/diffs/Engine.cpp.diff +++ b/src/override/diffs/Engine.cpp.diff @@ -1,4 +1,4 @@ ---- ../Rack/src/engine/Engine.cpp 2023-09-10 12:59:02.631898592 +0200 +--- ../Rack/src/engine/Engine.cpp 2023-12-17 12:57:01.138429358 +0100 +++ Engine.cpp 2023-05-22 04:26:39.902464764 +0200 @@ -1,3 +1,30 @@ +/* @@ -252,7 +252,7 @@ // Meter int meterCount = 0; double meterTotal = 0.0; -@@ -214,33 +98,32 @@ +@@ -214,37 +98,36 @@ double meterLastTime = -INFINITY; double meterLastAverage = 0.0; double meterLastMax = 0.0; @@ -300,6 +300,11 @@ }; +-static void Engine_updateExpander_NoLock(Engine* that, Module* module, uint8_t side) { ++static void Engine_updateExpander_NoLock(Engine* that, Module* module, bool side) { + Module::Expander& expander = side ? module->rightExpander : module->leftExpander; + Module* oldExpanderModule = expander.module; + @@ -268,89 +151,134 @@ } diff --git a/src/override/diffs/MenuBar.cpp.diff b/src/override/diffs/MenuBar.cpp.diff index 21099eb..3ad05a1 100644 --- a/src/override/diffs/MenuBar.cpp.diff +++ b/src/override/diffs/MenuBar.cpp.diff @@ -1,4 +1,4 @@ ---- ../Rack/src/app/MenuBar.cpp 2023-09-10 12:59:02.630898560 +0200 +--- ../Rack/src/app/MenuBar.cpp 2023-12-17 12:57:01.136429153 +0100 +++ MenuBar.cpp 2023-08-15 17:56:23.782915145 +0200 @@ -1,8 +1,33 @@ +/* @@ -248,26 +248,26 @@ + wasmSaveAs(); + else + patchUtils::saveDialog(APP->patch->path); - })); - -- menu->addChild(createMenuItem("Save as", RACK_MOD_CTRL_NAME "+Shift+S", []() { -- APP->patch->saveAsDialog(); ++ })); ++ + menu->addChild(createMenuItem("Save as...", "", []() { + wasmSaveAs(); })); -- menu->addChild(createMenuItem("Save a copy", "", []() { -- APP->patch->saveAsDialog(false); +- menu->addChild(createMenuItem("Save as", RACK_MOD_CTRL_NAME "+Shift+S", []() { +- APP->patch->saveAsDialog(); + menu->addChild(createMenuItem("Save and download compressed", "", []() { + patchUtils::saveAsDialog(); })); +- menu->addChild(createMenuItem("Save a copy", "", []() { +- APP->patch->saveAsDialog(false); + menu->addChild(createMenuItem("Save and download uncompressed", "", []() { + patchUtils::saveAsDialogUncompressed(); -+ })); + })); +#endif +#endif -+ + menu->addChild(createMenuItem("Revert", RACK_MOD_CTRL_NAME "+" RACK_MOD_SHIFT_NAME "+O", []() { - APP->patch->revertDialog(); - }, APP->patch->path == "")); @@ -462,11 +462,11 @@ static const std::vector knobModeLabels = { "Linear", -@@ -487,11 +692,34 @@ +@@ -487,13 +692,34 @@ menu->addChild(knobScrollSensitivitySlider); menu->addChild(new ui::MenuSeparator); -- menu->addChild(createMenuLabel("Module")); +- menu->addChild(createMenuLabel("Modules")); + menu->addChild(createMenuLabel("Window")); - menu->addChild(createBoolPtrMenuItem("Lock positions", "", &settings::lockModules)); @@ -480,9 +480,10 @@ + })); +#endif -- menu->addChild(createBoolPtrMenuItem("Auto-squeeze algorithm (experimental)", "", &settings::squeezeModules)); +- menu->addChild(createBoolPtrMenuItem("Smart rearrangement", "", &settings::squeezeModules)); + menu->addChild(createBoolPtrMenuItem("Invert zoom", "", &settings::invertZoom)); -+ + +- menu->addChild(createBoolPtrMenuItem("Use dark panels if available (experimental)", "", &settings::preferDarkPanels)); + static const std::vector rateLimitLabels = { + "None", + "2x", @@ -500,7 +501,7 @@ } }; -@@ -501,48 +729,11 @@ +@@ -503,48 +729,11 @@ //////////////////// @@ -553,7 +554,7 @@ void onAction(const ActionEvent& e) override { ui::Menu* menu = createMenu(); menu->cornerFlags = BND_CORNER_TOP; -@@ -555,269 +746,87 @@ +@@ -557,292 +746,87 @@ settings::cpuMeter ^= true; })); @@ -664,26 +665,42 @@ - return NULL; - library::UpdateInfo update = it->second; - -- if (update.changelogUrl == "") -- return NULL; -- - ui::Menu* menu = new ui::Menu; - -- std::string changelogUrl = update.changelogUrl; -- menu->addChild(createMenuItem("Changelog", "", [=]() { -- system::openBrowser(changelogUrl); -- })); +- if (update.minRackVersion != "") { +- menu->addChild(createMenuLabel(string::f("Requires Rack %s+", update.minRackVersion.c_str()))); +- } - +- if (update.changelogUrl != "") { +- std::string changelogUrl = update.changelogUrl; +- menu->addChild(createMenuItem("Changelog", "", [=]() { +- system::openBrowser(changelogUrl); +- })); +- } +- +- if (menu->children.empty()) { +- delete menu; +- return NULL; +- } - return menu; - } - - void step() override { -- disabled = library::isSyncing; +- disabled = false; +- +- if (library::isSyncing) +- disabled = true; - - auto it = library::updateInfos.find(slug); -- if (it != library::updateInfos.end()) { +- if (it == library::updateInfos.end()) { +- disabled = true; +- } +- else { - library::UpdateInfo update = it->second; - +- if (update.minRackVersion != "") +- disabled = true; +- - if (update.downloaded) { - rightText = CHECKMARK_STRING; - disabled = true; @@ -713,7 +730,7 @@ - rightText += update.version; - } - } - +- - MenuItem::step(); - } - @@ -725,18 +742,13 @@ - e.unconsume(); - } -}; -+ async_dialog_text_input("OSC network port", CARDINAL_DEFAULT_REMOTE_PORT, [=](char* const port) { -+ if (port == nullptr) -+ return; - -+ if (plugin->startRemoteServer(port)) -+ remoteServerStarted = true; - +- +- -struct LibraryMenu : ui::Menu { - LibraryMenu() { - refresh(); - } -- + - void step() override { - // Refresh menu when appropriate - if (library::refreshRequested) { @@ -745,11 +757,16 @@ - } - Menu::step(); - } -- ++ async_dialog_text_input("OSC network port", CARDINAL_DEFAULT_REMOTE_PORT, [=](char* const port) { ++ if (port == nullptr) ++ return; + - void refresh() { - setChildMenu(NULL); - clearChildren(); -- ++ if (plugin->startRemoteServer(port)) ++ remoteServerStarted = true; + - if (settings::devMode) { - addChild(createMenuLabel("Disabled in development mode")); - } @@ -759,9 +776,7 @@ + std::free(port); + }); })); -+ } -+#endif - +- - ui::TextField* emailField = new ui::TextField; - emailField->placeholder = "Email"; - emailField->box.size.x = 240.0; @@ -779,11 +794,34 @@ - logInItem->passwordField = passwordField; - passwordField->logInItem = logInItem; - addChild(logInItem); -- } + } - else { - addChild(createMenuItem("Log out", "", [=]() { - library::logOut(); - })); ++#endif + +- addChild(createMenuItem("Account settings", "", [=]() { +- system::openBrowser("https://vcvrack.com/account"); +- })); +- +- addChild(createMenuItem("Browse VCV Library", "", [=]() { +- system::openBrowser("https://library.vcvrack.com/"); +- })); +- +- SyncUpdatesItem* syncItem = new SyncUpdatesItem; +- syncItem->text = "Update all"; +- addChild(syncItem); +- +- if (!library::updateInfos.empty()) { +- addChild(new ui::MenuSeparator); +- addChild(createMenuLabel("Updates")); +- +- for (auto& pair : library::updateInfos) { +- SyncUpdateItem* updateItem = new SyncUpdateItem; +- updateItem->setUpdate(pair.first); +- addChild(updateItem); +- } + if (isUsingNativeAudio()) { + if (supportsAudioInput()) { + const bool enabled = isAudioInputEnabled(); @@ -794,11 +832,11 @@ + if (!enabled) + requestAudioInput(); + })); -+ } + } +- } +- } +-}; -- addChild(createMenuItem("Browse VCV Library", "", [=]() { -- system::openBrowser("https://library.vcvrack.com/"); -- })); + if (supportsMIDI()) { + std::string rightText; + if (isMIDIEnabled()) @@ -808,19 +846,26 @@ + })); + } -- SyncUpdatesItem* syncItem = new SyncUpdatesItem; -- syncItem->text = "Update all"; -- addChild(syncItem); +-struct LibraryButton : MenuButton { +- NotificationIcon* notification; - -- if (!library::updateInfos.empty()) { -- addChild(new ui::MenuSeparator); -- addChild(createMenuLabel("Updates")); +- LibraryButton() { +- notification = new NotificationIcon; +- addChild(notification); +- } - -- for (auto& pair : library::updateInfos) { -- SyncUpdateItem* updateItem = new SyncUpdateItem; -- updateItem->setUpdate(pair.first); -- addChild(updateItem); -- } +- void onAction(const ActionEvent& e) override { +- ui::Menu* menu = createMenu(); +- menu->cornerFlags = BND_CORNER_TOP; +- menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y)); +- +- // Check for updates when menu is opened +- if (!settings::devMode) { +- std::thread t([&]() { +- system::setThreadName("Library"); +- library::checkUpdates(); +- }); +- t.detach(); + if (supportsBufferSizeChanges()) { + static const std::vector bufferSizes = { + #ifdef DISTRHO_OS_WASM @@ -838,31 +883,9 @@ + )); + } + })); - } ++ } } } --}; -- -- --struct LibraryButton : MenuButton { -- NotificationIcon* notification; -- -- LibraryButton() { -- notification = new NotificationIcon; -- addChild(notification); -- } -- -- void onAction(const ActionEvent& e) override { -- ui::Menu* menu = createMenu(); -- menu->cornerFlags = BND_CORNER_TOP; -- menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y)); -- // Check for updates when menu is opened -- std::thread t([&]() { -- system::setThreadName("Library"); -- library::checkUpdates(); -- }); -- t.detach(); -- } +#ifdef HAVE_LIBLO void step() override { @@ -888,7 +911,7 @@ }; -@@ -827,63 +836,30 @@ +@@ -852,63 +836,30 @@ struct HelpButton : MenuButton { @@ -906,14 +929,14 @@ - menu->addChild(createMenuItem("Tips", "", [=]() { - APP->scene->addChild(tipWindowCreate()); -- })); -- -- menu->addChild(createMenuItem("User manual", "F1", [=]() { -- system::openBrowser("https://vcvrack.com/manual"); + menu->addChild(createMenuItem("Rack User manual", "F1", [=]() { + patchUtils::openBrowser("https://vcvrack.com/manual"); })); +- menu->addChild(createMenuItem("User manual", "F1", [=]() { +- system::openBrowser("https://vcvrack.com/manual"); +- })); +- - menu->addChild(createMenuItem("Support", "", [=]() { - system::openBrowser("https://vcvrack.com/support"); - })); @@ -960,7 +983,7 @@ } }; -@@ -926,15 +902,19 @@ +@@ -951,15 +902,19 @@ text = ""; @@ -983,7 +1006,7 @@ Label::step(); } -@@ -944,7 +924,9 @@ +@@ -969,7 +924,9 @@ struct MenuBar : widget::OpaqueWidget { InfoLabel* infoLabel; @@ -994,7 +1017,7 @@ const float margin = 5; box.size.y = BND_WIDGET_HEIGHT + 2 * margin; -@@ -953,7 +935,7 @@ +@@ -978,7 +935,7 @@ layout->spacing = math::Vec(0, 0); addChild(layout); @@ -1003,7 +1026,7 @@ fileButton->text = "File"; layout->addChild(fileButton); -@@ -965,13 +947,11 @@ +@@ -990,13 +947,11 @@ viewButton->text = "View"; layout->addChild(viewButton); @@ -1019,7 +1042,7 @@ HelpButton* helpButton = new HelpButton; helpButton->text = "Help"; -@@ -1003,7 +983,7 @@ +@@ -1028,7 +983,7 @@ widget::Widget* createMenuBar() { diff --git a/src/override/diffs/ModuleWidget.cpp.diff b/src/override/diffs/ModuleWidget.cpp.diff index 3217e3b..3de1e5d 100644 --- a/src/override/diffs/ModuleWidget.cpp.diff +++ b/src/override/diffs/ModuleWidget.cpp.diff @@ -1,4 +1,4 @@ ---- ../Rack/src/app/ModuleWidget.cpp 2023-09-10 12:59:02.630898560 +0200 +--- ../Rack/src/app/ModuleWidget.cpp 2023-12-17 12:57:01.136429153 +0100 +++ ModuleWidget.cpp 2023-05-20 18:40:08.948302802 +0200 @@ -1,8 +1,35 @@ +/* @@ -167,7 +167,20 @@ } })); } -@@ -1129,4 +1165,4 @@ +@@ -990,12 +1026,6 @@ + // Info + menu->addChild(createSubmenuItem("Info", "", [=](ui::Menu* menu) { + model->appendContextMenu(menu); +- +- if (!weakThis) +- return; +- menu->addChild(new ui::MenuSeparator); +- menu->addChild(createMenuLabel("Module instance ID:")); +- menu->addChild(createMenuLabel(string::f("%lld", (long long) weakThis->module->getId()))); + })); + + // Preset +@@ -1135,4 +1165,4 @@ } // namespace app diff --git a/src/override/diffs/Scene.cpp.diff b/src/override/diffs/Scene.cpp.diff index 6d9371e..d2071ae 100644 --- a/src/override/diffs/Scene.cpp.diff +++ b/src/override/diffs/Scene.cpp.diff @@ -1,5 +1,5 @@ --- ../Rack/src/app/Scene.cpp 2022-09-21 20:49:12.199540706 +0200 -+++ Scene.cpp 2023-07-03 09:30:14.548718644 +0200 ++++ Scene.cpp 2023-10-21 13:42:59.503556170 +0200 @@ -1,12 +1,36 @@ -#include - diff --git a/src/override/diffs/Window.cpp.diff b/src/override/diffs/Window.cpp.diff index fbd1894..ce7a88e 100644 --- a/src/override/diffs/Window.cpp.diff +++ b/src/override/diffs/Window.cpp.diff @@ -1,5 +1,5 @@ ---- ../Rack/src/window/Window.cpp 2023-09-10 12:59:02.631898592 +0200 -+++ Window.cpp 2023-08-28 09:55:57.292032175 +0200 +--- ../Rack/src/window/Window.cpp 2023-12-17 12:57:01.139429461 +0100 ++++ Window.cpp 2023-10-22 13:33:43.777041594 +0200 @@ -1,33 +1,94 @@ +/* + * DISTRHO Cardinal Plugin @@ -119,7 +119,7 @@ throw Exception("Failed to load font %s", filename.c_str()); } INFO("Loaded font %s", filename.c_str()); -@@ -79,338 +139,478 @@ +@@ -79,340 +139,478 @@ } @@ -194,7 +194,7 @@ + Internal() +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS + : hiddenApp(false), -+ hiddenWindow(hiddenApp) ++ hiddenWindow(hiddenApp, 0, DISTRHO_UI_DEFAULT_WIDTH, DISTRHO_UI_DEFAULT_HEIGHT, 0.0, true) + { + hiddenWindow.setIgnoringKeyRepeat(true); + hiddenApp.idle(); @@ -269,7 +269,7 @@ - int cursorMode = glfwGetInputMode(win, GLFW_CURSOR); - (void) cursorMode; +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS -+ DGL_NAMESPACE::Window::ScopedGraphicsContext sgc(internal->hiddenWindow); ++ const DGL_NAMESPACE::Window::ScopedGraphicsContext sgc(internal->hiddenWindow); + vg = nvgCreateGL(nvgFlags); +#else + vg = static_cast(APP)->tlw->getContext(); @@ -684,6 +684,7 @@ - if (APP->scene) { - widget::Widget::ContextCreateEvent e; +- e.vg = vg; - APP->scene->onContextCreate(e); +#if defined NANOVG_GLES2 + nvgDeleteGLES2(window->internal->r_fbVg); @@ -706,6 +707,7 @@ Window::~Window() { - if (APP->scene) { - widget::Widget::ContextDestroyEvent e; +- e.vg = vg; - APP->scene->onContextDestroy(e); - } + { @@ -852,7 +854,7 @@ double frameTime = system::getTime(); if (std::isfinite(internal->frameTime)) { internal->lastFrameDuration = frameTime - internal->frameTime; -@@ -422,57 +622,52 @@ +@@ -424,57 +622,52 @@ // Make event handlers and step() have a clean NanoVG context nvgReset(vg); @@ -945,7 +947,7 @@ windowRatio = (float)fbWidth / winWidth; // t1 = system::getTime(); -@@ -486,10 +681,8 @@ +@@ -488,10 +681,8 @@ // t2 = system::getTime(); // Render scene @@ -957,7 +959,7 @@ nvgScale(vg, pixelRatio, pixelRatio); // Draw scene -@@ -500,23 +693,16 @@ +@@ -502,23 +693,16 @@ // t3 = system::getTime(); glViewport(0, 0, fbWidth, fbHeight); @@ -985,7 +987,7 @@ // t5 = system::getTime(); // DEBUG("pre-step %6.1f step %6.1f draw %6.1f nvgEndFrame %6.1f glfwSwapBuffers %6.1f total %6.1f", // (t1 - frameTime) * 1e3f, -@@ -526,163 +712,132 @@ +@@ -528,168 +712,132 @@ // (t5 - t4) * 1e3f, // (t5 - frameTime) * 1e3f // ); @@ -1068,6 +1070,11 @@ void Window::screenshotModules(const std::string& screenshotsDir, float zoom) { +- // Disable preferDarkPanels +- bool preferDarkPanels = settings::preferDarkPanels; +- settings::preferDarkPanels = false; +- DEFER({settings::preferDarkPanels = preferDarkPanels;}); +- - // Iterate plugins and create directories - system::createDirectories(screenshotsDir); - for (plugin::Plugin* p : plugin::plugins) { @@ -1227,7 +1234,7 @@ } -@@ -702,7 +857,7 @@ +@@ -709,7 +857,7 @@ double Window::getFrameDurationRemaining() { @@ -1236,7 +1243,7 @@ return frameDuration - (system::getTime() - internal->frameTime); } -@@ -713,14 +868,15 @@ +@@ -720,14 +868,15 @@ return pair->second; // Load font @@ -1255,7 +1262,7 @@ } internal->fontCache[filename] = font; return font; -@@ -733,14 +889,15 @@ +@@ -740,14 +889,15 @@ return pair->second; // Load image @@ -1274,7 +1281,7 @@ } internal->imageCache[filename] = image; return image; -@@ -757,28 +914,156 @@ +@@ -764,28 +914,156 @@ } diff --git a/src/override/diffs/context.cpp.diff b/src/override/diffs/context.cpp.diff index 0987ca0..904d91f 100644 --- a/src/override/diffs/context.cpp.diff +++ b/src/override/diffs/context.cpp.diff @@ -1,4 +1,4 @@ ---- ../Rack/src/context.cpp 2023-09-10 12:59:02.630898560 +0200 +--- ../Rack/src/context.cpp 2023-12-17 12:57:01.137429255 +0100 +++ context.cpp 2023-05-20 18:08:56.497736615 +0200 @@ -1,14 +1,44 @@ +/* @@ -47,7 +47,7 @@ Context::~Context() { // Deleting NULL is safe in C++. -@@ -38,17 +68,13 @@ +@@ -38,16 +68,13 @@ INFO("Deleting engine"); delete engine; engine = NULL; @@ -61,7 +61,6 @@ static thread_local Context* threadContext = NULL; Context* contextGet() { -- assert(threadContext); + DISTRHO_SAFE_ASSERT(threadContext != nullptr); return threadContext; } diff --git a/src/override/diffs/engine-Port.hpp.diff b/src/override/diffs/engine-Port.hpp.diff index 7fad783..f3dad51 100644 --- a/src/override/diffs/engine-Port.hpp.diff +++ b/src/override/diffs/engine-Port.hpp.diff @@ -1,4 +1,4 @@ ---- ../Rack/include/engine/Port.hpp 2023-09-10 12:59:02.629898529 +0200 +--- ../Rack/include/engine/Port.hpp 2023-12-17 12:57:01.129428435 +0100 +++ ../../include/engine/Port.hpp 2023-07-07 18:20:12.030329564 +0200 @@ -1,19 +1,57 @@ +/* @@ -60,11 +60,11 @@ /** Unstable API. Use getVoltage() and setVoltage() instead. */ float voltages[PORT_MAX_CHANNELS] = {}; /** DEPRECATED. Unstable API. Use getVoltage() and setVoltage() instead. */ -@@ -40,40 +78,40 @@ +@@ -40,41 +78,41 @@ }; /** Sets the voltage of the given channel. */ -- void setVoltage(float voltage, int channel = 0) { +- void setVoltage(float voltage, uint8_t channel = 0) { + void setVoltage(float voltage, int channel = 0) noexcept { voltages[channel] = voltage; } @@ -72,24 +72,24 @@ /** Returns the voltage of the given channel. Because of proper bookkeeping, all channels higher than the input port's number of channels should be 0V. */ -- float getVoltage(int channel = 0) { +- float getVoltage(uint8_t channel = 0) { + float getVoltage(int channel = 0) const noexcept { return voltages[channel]; } /** Returns the given channel's voltage if the port is polyphonic, otherwise returns the first voltage (channel 0). */ -- float getPolyVoltage(int channel) { +- float getPolyVoltage(uint8_t channel) { + float getPolyVoltage(int channel) const noexcept { return isMonophonic() ? getVoltage(0) : getVoltage(channel); } /** Returns the voltage if a cable is connected, otherwise returns the given normal voltage. */ -- float getNormalVoltage(float normalVoltage, int channel = 0) { +- float getNormalVoltage(float normalVoltage, uint8_t channel = 0) { + float getNormalVoltage(float normalVoltage, int channel = 0) const noexcept { return isConnected() ? getVoltage(channel) : normalVoltage; } -- float getNormalPolyVoltage(float normalVoltage, int channel) { +- float getNormalPolyVoltage(float normalVoltage, uint8_t channel) { + float getNormalPolyVoltage(float normalVoltage, int channel) const noexcept { return isConnected() ? getPolyVoltage(channel) : normalVoltage; } @@ -97,24 +97,34 @@ /** Returns a pointer to the array of voltages beginning with firstChannel. The pointer can be used for reading and writing. */ -- float* getVoltages(int firstChannel = 0) { +- float* getVoltages(uint8_t firstChannel = 0) { + float* getVoltages(int firstChannel = 0) noexcept { return &voltages[firstChannel]; } /** Copies the port's voltages to an array of size at least `channels`. */ - void readVoltages(float* v) { +- for (uint8_t c = 0; c < channels; c++) { + void readVoltages(float* v) const noexcept { - for (int c = 0; c < channels; c++) { ++ for (int c = 0; c < channels; c++) { v[c] = voltages[c]; } -@@ -89,14 +127,14 @@ + } +@@ -83,22 +121,22 @@ + Remember to set the number of channels *before* calling this method. + */ + void writeVoltages(const float* v) { +- for (uint8_t c = 0; c < channels; c++) { ++ for (int c = 0; c < channels; c++) { + voltages[c] = v[c]; + } } /** Sets all voltages to 0. */ - void clearVoltages() { +- for (uint8_t c = 0; c < channels; c++) { + void clearVoltages() noexcept { - for (int c = 0; c < channels; c++) { ++ for (int c = 0; c < channels; c++) { voltages[c] = 0.f; } } @@ -123,8 +133,11 @@ - float getVoltageSum() { + float getVoltageSum() const noexcept { float sum = 0.f; - for (int c = 0; c < channels; c++) { +- for (uint8_t c = 0; c < channels; c++) { ++ for (int c = 0; c < channels; c++) { sum += voltages[c]; + } + return sum; @@ -107,7 +145,7 @@ /** Returns the root-mean-square of all voltages. Uses sqrt() which is slow, so use a custom approximation if calling frequently. @@ -134,45 +147,61 @@ if (channels == 0) { return 0.f; } -@@ -124,22 +162,22 @@ +@@ -116,7 +154,7 @@ + } + else { + float sum = 0.f; +- for (uint8_t c = 0; c < channels; c++) { ++ for (int c = 0; c < channels; c++) { + sum += std::pow(voltages[c], 2); + } + return std::sqrt(sum); +@@ -124,27 +162,27 @@ } template -- T getVoltageSimd(int firstChannel) { +- T getVoltageSimd(uint8_t firstChannel) { + T getVoltageSimd(int firstChannel) const noexcept { return T::load(&voltages[firstChannel]); } template -- T getPolyVoltageSimd(int firstChannel) { +- T getPolyVoltageSimd(uint8_t firstChannel) { + T getPolyVoltageSimd(int firstChannel) const noexcept { return isMonophonic() ? getVoltage(0) : getVoltageSimd(firstChannel); } template -- T getNormalVoltageSimd(T normalVoltage, int firstChannel) { +- T getNormalVoltageSimd(T normalVoltage, uint8_t firstChannel) { + T getNormalVoltageSimd(T normalVoltage, int firstChannel) const noexcept { return isConnected() ? getVoltageSimd(firstChannel) : normalVoltage; } template -- T getNormalPolyVoltageSimd(T normalVoltage, int firstChannel) { +- T getNormalPolyVoltageSimd(T normalVoltage, uint8_t firstChannel) { + T getNormalPolyVoltageSimd(T normalVoltage, int firstChannel) const noexcept { return isConnected() ? getPolyVoltageSimd(firstChannel) : normalVoltage; } + template +- void setVoltageSimd(T voltage, uint8_t firstChannel) { ++ void setVoltageSimd(T voltage, int firstChannel) { + voltage.store(&voltages[firstChannel]); + } + @@ -153,13 +191,15 @@ If disconnected, this does nothing (`channels` remains 0). If 0 is given, `channels` is set to 1 but all voltages are cleared. */ -- void setChannels(int channels) { +- void setChannels(uint8_t channels) { + void setChannels(int channels) noexcept { // If disconnected, keep the number of channels at 0. if (this->channels == 0) { return; } // Set higher channel voltages to 0 - for (int c = channels; c < this->channels; c++) { +- for (uint8_t c = channels; c < this->channels; c++) { ++ for (int c = channels; c < this->channels; c++) { + if (c >= PORT_MAX_CHANNELS) + __builtin_unreachable(); voltages[c] = 0.f; diff --git a/src/override/diffs/plugin.cpp.diff b/src/override/diffs/plugin.cpp.diff index d4fe4bf..53746be 100644 --- a/src/override/diffs/plugin.cpp.diff +++ b/src/override/diffs/plugin.cpp.diff @@ -1,6 +1,6 @@ ---- ../Rack/src/plugin.cpp 2023-09-10 12:59:02.631898592 +0200 +--- ../Rack/src/plugin.cpp 2023-12-17 12:57:01.138429358 +0100 +++ plugin.cpp 2023-05-20 18:43:27.496323540 +0200 -@@ -1,356 +1,46 @@ +@@ -1,363 +1,46 @@ -#include -#include -#include @@ -134,14 +134,7 @@ - libraryExt = "dylib"; -#endif - --#if defined ARCH_X64 -- // Use `plugin.EXT` on x64 for backward compatibility. -- // Change to `plugin-OS-CPU.EXT` in Rack 3. - std::string libraryFilename = "plugin." + libraryExt; --#else -- // Use `plugin-CPU.EXT` on other CPUs like ARM64 -- std::string libraryFilename = "plugin-" + APP_CPU + "." + libraryExt; --#endif - std::string libraryPath = system::join(plugin->path, libraryFilename); - - // Check file existence @@ -291,9 +284,23 @@ - // Load Core - loadPlugin(""); - -- pluginsPath = asset::user("plugins"); -- - // Get user plugins directory +- if (settings::devMode) { +- pluginsPath = asset::user("plugins"); +- } +- else { +- pluginsPath = asset::user("plugins-" + APP_OS + "-" + APP_CPU); +- } +- +- // In Rack <2.4.0, plugins dir was "plugins" regardless of arch. +- // Rename old dir if running x64. +-#if defined ARCH_X64 +- std::string oldPluginsPath = asset::user("plugins"); +- if (system::isDirectory(oldPluginsPath)) { +- system::rename(oldPluginsPath, pluginsPath); +- } +-#endif +- - system::createDirectory(pluginsPath); - - // Don't load plugins if safe mode is enabled @@ -387,7 +394,15 @@ */ static const std::map pluginSlugFallbacks = { {"VultModulesFree", "VultModules"}, -@@ -399,8 +89,19 @@ +@@ -365,7 +48,6 @@ + {"AudibleInstrumentsPreview", "AudibleInstruments"}, + {"SequelSequencers", "DanielDavies"}, + {"DelexanderVol1", "DelexandraVol1"}, +- {"VCV-Pro", "Fundamental"}, + // {"", ""}, + }; + +@@ -407,8 +89,19 @@ */ using PluginModuleSlug = std::tuple; static const std::map moduleSlugFallbacks = { @@ -408,7 +423,7 @@ // {{"", ""}, {"", ""}}, }; -@@ -488,7 +189,6 @@ +@@ -496,7 +189,6 @@ } diff --git a/utils/macOS/Info_JACK.plist b/utils/macOS/Info_JACK.plist index 4b6644c..b8e72f9 100644 --- a/utils/macOS/Info_JACK.plist +++ b/utils/macOS/Info_JACK.plist @@ -11,7 +11,7 @@ CFBundleIdentifier studio.kx.distrho.cardinal.jack CFBundleShortVersionString - 23.10 + 23.01 LSMinimumSystemVersion 10.15 NSHumanReadableCopyright diff --git a/utils/macOS/Info_Native.plist b/utils/macOS/Info_Native.plist index e1e6d35..2fd3e06 100644 --- a/utils/macOS/Info_Native.plist +++ b/utils/macOS/Info_Native.plist @@ -11,7 +11,7 @@ CFBundleIdentifier studio.kx.distrho.cardinal.native CFBundleShortVersionString - 23.10 + 24.01 LSMinimumSystemVersion 10.15 NSHumanReadableCopyright