#!/bin/bash # Installs (or updates) all the Plumppu tools on an Apple Silicon Mac: # # PlumppuVox Ren VST3 -> ~/Library/Audio/Plug-Ins/VST3/PlumppuVox.vst3 # PlumppuVox Lagom VST3 -> ~/Library/Audio/Plug-Ins/VST3/PlumppuLagom.vst3 # Plumppu Radiomix app -> /Applications (or ~/Applications) # # curl -fsSL https:///pa | bash # # Downloads the newest builds from the "main-build" GitHub release. They are # not notarized by Apple, so the script takes them out of Gatekeeper's # quarantine (after checking their signatures) and they open without the # "cannot be verified" warning. No admin rights needed. Run it again to update. # # Environment override: # PLUMPPU_RELEASE download from a different release URL # Everything lives in main(), called on the last line, so a download cut short # while piping into bash runs nothing at all. main() { set -euo pipefail local release="${PLUMPPU_RELEASE:-https://github.com/inthevidual/plumppuvox/releases/download/main-build}" local plugins="$HOME/Library/Audio/Plug-Ins/VST3" local apps="/Applications" [ -w "$apps" ] || apps="$HOME/Applications" say() { printf '\033[1m==>\033[0m %s\n' "$*"; } warn() { printf '\033[1;33mWarning:\033[0m %s\n' "$*" >&2; } die() { printf '\033[1;31mError:\033[0m %s\n' "$*" >&2; exit 1; } [ "$(uname -s)" = Darwin ] || die "this installer is for macOS." # Under Rosetta, uname reports x86_64 even on Apple Silicon; ask the kernel. if [ "$(uname -m)" != arm64 ] && [ "$(sysctl -in hw.optional.arm64 2>/dev/null)" != 1 ]; then die "the Plumppu tools are built for Apple Silicon (M-series) Macs only." fi # Global, not local: the EXIT trap runs after main has returned. tmp="$(mktemp -d -t plumppu)" trap 'rm -rf "$tmp"' EXIT local failed=() # install_one install_one() { local name="$1" zip="$2" bundle="$3" exe="$4" dest="$5" local work="$tmp/$zip" say "Downloading $name" if ! curl -fL --progress-bar --retry 3 -o "$work.zip" "$release/$zip"; then warn "could not download $name ($release/$zip)." failed+=("$name"); return fi if ! ditto -x -k "$work.zip" "$work" || [ ! -f "$work/$bundle/Contents/MacOS/$exe" ]; then warn "the $name download does not contain $bundle." failed+=("$name"); return fi # Gatekeeper: take the bundle out of quarantine, so macOS loads the # plugin and opens the app without asking. Only if it is intact. xattr -dr com.apple.quarantine "$work/$bundle" 2>/dev/null || true if ! codesign --verify --deep "$work/$bundle" 2>/dev/null; then warn "$name's signature does not verify; not installing it." failed+=("$name"); return fi mkdir -p "$dest" rm -rf "${dest:?}/$bundle" ditto "$work/$bundle" "$dest/$bundle" xattr -dr com.apple.quarantine "$dest/$bundle" 2>/dev/null || true say "$name installed in $dest" } install_one "PlumppuVox Ren" PlumppuVox-macOS-AppleSilicon.zip PlumppuVox.vst3 PlumppuVox "$plugins" install_one "PlumppuVox Lagom" PlumppuLagom-macOS-AppleSilicon.zip PlumppuLagom.vst3 PlumppuLagom "$plugins" install_one "Plumppu Radiomix" PlumppuRadiomix-macOS-AppleSilicon.zip "Plumppu Radiomix.app" "Plumppu Radiomix" "$apps" # Radiomix reads and writes video with ffmpeg if ! command -v ffmpeg >/dev/null && [ ! -x /opt/homebrew/bin/ffmpeg ] && [ ! -x /usr/local/bin/ffmpeg ]; then warn "Radiomix needs ffmpeg for video files (plain audio works without it): brew install ffmpeg" fi echo if [ ${#failed[@]} -gt 0 ]; then die "not installed: ${failed[*]}." fi say "All done. Rescan plugins (or restart) in your host to pick up Ren and Lagom." } main "$@"