From 5fe4a45df41eef66cf218a47159867f84f538268 Mon Sep 17 00:00:00 2001 From: Boof2015 <75185879+Boof2015@users.noreply.github.com> Date: Mon, 1 Jun 2026 18:27:33 -0400 Subject: [PATCH] new workflow, add windows support for vst, switch to pkg --- .github/workflows/release.yml | 47 ++++++++++++++++- .gitignore | 5 ++ package.json | 13 ++++- plugin/CMakeLists.txt | 11 +++- plugin/README.md | 52 ++++++++++++++----- plugin/Source/PluginEditor.cpp | 11 +++- resources/installer/macos-scripts/postinstall | 32 ++++++++++++ resources/installer/windows-vst3.nsh | 25 +++++++++ 8 files changed, 180 insertions(+), 16 deletions(-) create mode 100755 resources/installer/macos-scripts/postinstall create mode 100644 resources/installer/windows-vst3.nsh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 716100e..61f80e1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -61,6 +61,51 @@ jobs: fi echo "Native module built successfully: $(ls -lh native/build/Release/visualizer_dsp.node)" + # --- JUCE plugins (macOS + Windows). Linux defers; we still create the + # staging dir so electron-builder's extraResources entry doesn't choke. --- + + - name: Build plugin webview bundle + if: runner.os != 'Linux' + run: npm run plugin-ui:build + + - name: Configure JUCE plugins (macOS) + if: runner.os == 'macOS' + run: cmake -B plugin/build -S plugin -DCMAKE_BUILD_TYPE=Release + + - name: Configure JUCE plugins (Windows) + if: runner.os == 'Windows' + run: cmake -B plugin/build -S plugin -G "Visual Studio 17 2022" -A x64 + + - name: Build JUCE plugins + if: runner.os != 'Linux' + run: cmake --build plugin/build --config Release + + - name: Stage plugins for installer + shell: bash + run: | + rm -rf plugin/dist-installer + mkdir -p plugin/dist-installer + if [ "$RUNNER_OS" = "Linux" ]; then + echo "Linux: skipping plugin staging (no DAW-plugin install path yet)." + exit 0 + fi + mkdir -p plugin/dist-installer/VST3 + [ "$RUNNER_OS" = "macOS" ] && mkdir -p plugin/dist-installer/AU + for art in PrismSpectrum PrismOscilloscope PrismVUMeter PrismLUFSMeter PrismVectorscope PrismSpectrogram PrismWaveform; do + vst3_dir="plugin/build/${art}_artefacts/Release/VST3" + [ -d "$vst3_dir" ] && find "$vst3_dir" -maxdepth 1 -name "*.vst3" -exec cp -R {} plugin/dist-installer/VST3/ \; + if [ "$RUNNER_OS" = "macOS" ]; then + au_dir="plugin/build/${art}_artefacts/Release/AU" + [ -d "$au_dir" ] && find "$au_dir" -maxdepth 1 -name "*.component" -exec cp -R {} plugin/dist-installer/AU/ \; + fi + done + echo "--- staged VST3 ---" + ls -la plugin/dist-installer/VST3 || true + if [ "$RUNNER_OS" = "macOS" ]; then + echo "--- staged AU ---" + ls -la plugin/dist-installer/AU || true + fi + - name: Build distributable run: npm run ${{ matrix.dist_cmd }} env: @@ -72,7 +117,7 @@ jobs: name: prism-${{ runner.os }}${{ inputs.version_tag && format('-{0}', inputs.version_tag) || '' }} path: | dist/*.exe - dist/*.dmg + dist/*.pkg dist/*.zip dist/*.AppImage dist/*.deb diff --git a/.gitignore b/.gitignore index 2269308..25def0d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,11 @@ out/ dist/ native/build/ +# JUCE plugin build + installer staging +plugin/build/ +plugin/webview-dist/ +plugin/dist-installer/ + # Electron *.log diff --git a/package.json b/package.json index f94304a..88fdf9a 100644 --- a/package.json +++ b/package.json @@ -92,16 +92,24 @@ { "from": "resources/icon.png", "to": "icon.png" + }, + { + "from": "plugin/dist-installer/", + "to": "plugins/" } ], "mac": { - "target": ["dmg", "zip"], + "target": ["pkg", "zip"], "icon": "resources/icon.icns", "category": "public.app-category.music", "hardenedRuntime": true, "entitlements": "resources/entitlements.mac.plist", "entitlementsInherit": "resources/entitlements.mac.inherit.plist" }, + "pkg": { + "installLocation": "/Applications", + "scripts": "resources/installer/macos-scripts" + }, "win": { "target": [ { "target": "nsis", "arch": ["x64"] }, @@ -109,6 +117,9 @@ ], "icon": "resources/icon.ico" }, + "nsis": { + "include": "resources/installer/windows-vst3.nsh" + }, "linux": { "target": ["AppImage", "deb"], "icon": "resources/icon.png", diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index b5fd3b1..2d9d00c 100644 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -1,5 +1,14 @@ cmake_minimum_required(VERSION 3.22) +# macOS deployment target. Without an override, the build inherits the host SDK +# (e.g. 26 on a current Mac) which restricts the plugin to that macOS or newer. +# 11.0 (Big Sur) is a reasonable floor; well within JUCE 8's supported range. +# Override on the command line with -DCMAKE_OSX_DEPLOYMENT_TARGET=X.X — the FORCE +# is only applied when the value is empty/unset, so explicit overrides win. +if(NOT CMAKE_OSX_DEPLOYMENT_TARGET) + set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0" CACHE STRING "Minimum macOS version supported" FORCE) +endif() + project(PrismPlugins VERSION 0.1.0 LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 17) @@ -49,7 +58,7 @@ function(add_prism_scope TARGET PRODUCT PLUGIN_CODE SCOPE_DEFINE) NEEDS_MIDI_INPUT FALSE NEEDS_MIDI_OUTPUT FALSE IS_MIDI_EFFECT FALSE - NEEDS_WEBVIEW2 FALSE # macOS uses WKWebView; flip on for Windows later + NEEDS_WEBVIEW2 TRUE # Windows: links Microsoft Edge WebView2. No-op elsewhere. COPY_PLUGIN_AFTER_BUILD TRUE) target_sources(${TARGET} PRIVATE diff --git a/plugin/README.md b/plugin/README.md index 3811793..9c1fbce 100644 --- a/plugin/README.md +++ b/plugin/README.md @@ -1,9 +1,11 @@ -# Prism Spectrum — DAW plugin POC +# Prism — DAW plugins -A proof-of-concept JUCE 8 plugin (VST3 / AU / Standalone, macOS) that renders Prism's -Spectrum scope inside a DAW. It **reuses Prism's existing C++ DSP** (`native/src/spectrum.cpp`, -`dsp_utils.cpp`) and the **existing React canvas UI** (`src/plugin-ui`, which imports -`src/renderer/visualizers/SpectrumAnalyzer.ts`). +JUCE 8 plugins (VST3 / AU / Standalone) that render Prism's scopes inside a DAW — +one plugin per scope: **spectrum, oscilloscope, vectorscope, spectrogram, VU meter, +loudness meter, waveform**. They **reuse Prism's existing C++ DSP** (`native/src/*.cpp`) +and the **existing React canvas UI** (`src/plugin-ui`, importing the unchanged +visualizers from `src/renderer/visualizers/`). Built for macOS and Windows; Linux +untested but should follow the same recipe. ## How it fits together @@ -33,12 +35,13 @@ cmake -B plugin/build -S plugin -DCMAKE_BUILD_TYPE=Release # embeds the bundle ( cmake --build plugin/build --config Release ``` -`COPY_PLUGIN_AFTER_BUILD` installs into your user plugin folders: -- AU: `~/Library/Audio/Plug-Ins/Components/Prism Spectrum.component` -- VST3: `~/Library/Audio/Plug-Ins/VST3/Prism Spectrum.vst3` +`COPY_PLUGIN_AFTER_BUILD` installs all seven plugins into your user plugin folders: +- AU: `~/Library/Audio/Plug-Ins/Components/Prism *.component` +- VST3: `~/Library/Audio/Plug-Ins/VST3/Prism *.vst3` -Run the **Standalone** (`plugin/build/.../Standalone/Prism Spectrum.app`) or load the -VST3/AU on a track in Ableton / FL / Logic / Reaper, play audio, and the spectrum animates. +Load any `Prism *` AU / VST3 on a track in Ableton / FL / Logic / Reaper (or run the +matching **Standalone** from `plugin/build/Prism*_artefacts/Release/Standalone/`), +play audio, and the scope animates. (To use a local JUCE checkout instead of fetching: add `-DJUCE_PATH=/path/to/JUCE`.) ### UI development: dev-server mode (hot reload) @@ -53,6 +56,29 @@ Edit React → the plugin window hot-reloads. The UI also runs in a plain browse `http://localhost:5174` (no JUCE host → it shows a synthetic spectrum so the UI is developable outside a DAW). Reconfigure without `-DPRISM_DEV_SERVER=ON` to go back to embedded. +## Build & run (Windows) + +Prereqs: Visual Studio 2022 with the "Desktop development with C++" workload, +CMake ≥ 3.22, Node.js. Modern Win10 / Win11 ships with the Microsoft Edge WebView2 +Runtime preinstalled; if it's missing, install the "Evergreen Standalone Installer" +from Microsoft. + +```sh +npm install +npm run plugin-ui:build +cmake -B plugin\build -S plugin -G "Visual Studio 17 2022" -A x64 +cmake --build plugin\build --config Release +``` + +`COPY_PLUGIN_AFTER_BUILD` targets the system VST3 folder +(`C:\Program Files\Common Files\VST3\Prism *.vst3`), which **needs admin +privileges**. Either run the `cmake --build` step from an elevated shell, or copy +the built bundles from `plugin\build\Prism*_artefacts\Release\VST3\` into your +user-local VST3 folder (`%LOCALAPPDATA%\Programs\Common\VST3\`) by hand — most +DAWs scan both. + +Dev-server mode works the same as macOS: `-DPRISM_DEV_SERVER=ON` + `npm run plugin-ui:dev`. + ## Notes - **Refresh rate (macOS):** frames are emitted on `juce::VBlankAttachment` (synced to the @@ -62,5 +88,7 @@ developable outside a DAW). Reconfigure without `-DPRISM_DEV_SERVER=ON` to go ba `PreferPageRenderingUpdatesNear60FPSEnabled` feature on the live web view (no public API exists; fine for a non-App-Store FOSS plugin). To diagnose, set `showFpsMeter` on `` to overlay `render / data` fps. -- **Windows (later):** bump `NEEDS_WEBVIEW2 TRUE`; the DSP is already cross-platform. The - frame-rate workaround is macOS-only (WebView2 has its own rate behavior). +- **Windows:** `NEEDS_WEBVIEW2 TRUE` in CMake links Microsoft's Edge WebView2 runtime. + The macOS 120 Hz uncap (`Source/WebViewFrameRate.mm`, gated `if(APPLE)`) doesn't + apply — WebView2 has its own rate behavior; please report actual fps if it ever + feels low. diff --git a/plugin/Source/PluginEditor.cpp b/plugin/Source/PluginEditor.cpp index b997867..d0d0384 100644 --- a/plugin/Source/PluginEditor.cpp +++ b/plugin/Source/PluginEditor.cpp @@ -172,10 +172,19 @@ void PrismSpectrumEditor::pushRestoreSettings() void PrismSpectrumEditor::sendAppDefaults() { - // macOS userApplicationDataDirectory is ~/Library, so append "Application Support". + // Resolve Prism's app-data dir to match Electron's userData per platform. + // macOS: userApplicationDataDirectory == ~/Library, so the Electron path is + // ~/Library/Application Support/prism (the extra subfolder only exists on mac). + // Windows/Linux: JUCE's userApplicationDataDirectory already points at the right + // per-platform config root (%APPDATA% / ~/.config), so no extra append needed. + #if JUCE_MAC const auto appData = juce::File::getSpecialLocation(juce::File::userApplicationDataDirectory) .getChildFile("Application Support") .getChildFile("prism"); + #else + const auto appData = juce::File::getSpecialLocation(juce::File::userApplicationDataDirectory) + .getChildFile("prism"); + #endif const auto docs = juce::File::getSpecialLocation(juce::File::userDocumentsDirectory); const auto themesDir = docs.getChildFile("Prism Themes"); const auto profilesDir = docs.getChildFile("Prism Profiles"); diff --git a/resources/installer/macos-scripts/postinstall b/resources/installer/macos-scripts/postinstall new file mode 100755 index 0000000..235bfc6 --- /dev/null +++ b/resources/installer/macos-scripts/postinstall @@ -0,0 +1,32 @@ +#!/bin/bash +# Postinstall: after the macOS Installer drops Prism.app into /Applications, copy +# the bundled VST3 / AU plugins out of the app's Resources into the system +# Audio Plug-Ins folders so DAWs find them. +# +# Standard pkg postinstall args: +# $1 = full path to the installer package +# $2 = full path of the installed destination (e.g. /Applications) +# $3 = mountpoint of the target volume (typically /) +# $4 = root directory of the system being installed onto +# +# Runs as root, so writes to /Library/Audio/Plug-Ins/* succeed. + +set -eu + +APP_PATH="${2:-/Applications}/Prism.app" +[ -d "$APP_PATH" ] || APP_PATH="/Applications/Prism.app" + +PLUGINS_SRC="$APP_PATH/Contents/Resources/plugins" +VST3_DEST="/Library/Audio/Plug-Ins/VST3" +AU_DEST="/Library/Audio/Plug-Ins/Components" + +mkdir -p "$VST3_DEST" "$AU_DEST" + +if [ -d "$PLUGINS_SRC/VST3" ]; then + cp -R "$PLUGINS_SRC/VST3/"*.vst3 "$VST3_DEST/" 2>/dev/null || true +fi +if [ -d "$PLUGINS_SRC/AU" ]; then + cp -R "$PLUGINS_SRC/AU/"*.component "$AU_DEST/" 2>/dev/null || true +fi + +exit 0 diff --git a/resources/installer/windows-vst3.nsh b/resources/installer/windows-vst3.nsh new file mode 100644 index 0000000..19aa96d --- /dev/null +++ b/resources/installer/windows-vst3.nsh @@ -0,0 +1,25 @@ +; Custom NSIS include for electron-builder. +; +; After the main Prism app install finishes, copy the bundled VST3 plugin +; bundles out of $INSTDIR\resources\plugins\VST3\ into the system VST3 folder +; (C:\Program Files\Common Files\VST3\) so DAWs find them. On uninstall, remove +; them. The main NSIS installer already requested admin elevation (it has to, +; for Program Files), so writes to CommonFiles64 succeed without a second UAC. + +!macro customInstall + ; Ensure the destination exists; xcopy creates trees but not the leaf root. + CreateDirectory "$COMMONFILES64\VST3" + ; xcopy /E recurse, /I treat dest as dir, /Y overwrite without prompt. + ; The trailing "\*" + "/E" copies each *.vst3 bundle subfolder verbatim. + nsExec::ExecToLog 'cmd.exe /c xcopy /E /I /Y "$INSTDIR\resources\plugins\VST3\*" "$COMMONFILES64\VST3\"' +!macroend + +!macro customUnInstall + RMDir /r "$COMMONFILES64\VST3\Prism Spectrum.vst3" + RMDir /r "$COMMONFILES64\VST3\Prism Oscilloscope.vst3" + RMDir /r "$COMMONFILES64\VST3\Prism VU Meter.vst3" + RMDir /r "$COMMONFILES64\VST3\Prism Loudness Meter.vst3" + RMDir /r "$COMMONFILES64\VST3\Prism Vectorscope.vst3" + RMDir /r "$COMMONFILES64\VST3\Prism Spectrogram.vst3" + RMDir /r "$COMMONFILES64\VST3\Prism Waveform.vst3" +!macroend