#!/usr/bin/env bash # build.sh — compile all Faust DSP files in this directory to WASM + JSON # # Required tools: # faust >= 2.60.0 (https://faust.grame.fr / nix: faust) # emcc >= 3.1.x (Emscripten, already present at /usr/lib/emscripten/emcc) # # Usage: # cd playground/faust && ./build.sh # # Outputs (alongside each .dsp): # .wasm — compiled audio DSP binary # .json — Faust UI descriptor (consumed by faustJsonToParamMeta) # .js — JS glue / AudioWorklet wrapper generated by faust2wasm # # The JSON descriptor is the key artifact: it contains the full UI tree # (hslider / vslider / nentry / groups) that faustJsonToParamMeta.js parses # into the playground's standard paramMeta format. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" # --------------------------------------------------------------------------- # Dependency checks # --------------------------------------------------------------------------- if ! command -v faust &>/dev/null; then echo "" echo "ERROR: 'faust' not found in PATH." echo "" echo "Install options:" echo " nix-shell -p faust # one-off" echo " nix profile install nixpkgs#faust # permanent" echo " Or download from: https://faust.grame.fr/downloads/" echo "" echo "Required version: >= 2.60.0" echo "Check: faust --version" exit 1 fi FAUST_VER="$(faust --version 2>&1 | head -1)" echo "faust: $FAUST_VER" # emcc is optional — faust -lang wasm doesn't require it. # It is needed if you want to link extra C++ into the WASM module. if command -v emcc &>/dev/null; then EMCC_VER="$(emcc --version 2>&1 | head -1)" echo "emcc : $EMCC_VER" else echo "emcc : not found (not required for basic faust -lang wasm builds)" fi echo "" # --------------------------------------------------------------------------- # Compile each .dsp # --------------------------------------------------------------------------- DSP_FILES=("$SCRIPT_DIR"/*.dsp) if [ ${#DSP_FILES[@]} -eq 0 ]; then echo "No .dsp files found in $SCRIPT_DIR" exit 0 fi for DSP in "${DSP_FILES[@]}"; do NAME="$(basename "$DSP" .dsp)" echo "Compiling $NAME.dsp ..." # Step 1: emit WASM binary + JS glue # -lang wasm — target WebAssembly # -cn — class name prefix in generated JS # -e — export all DSP metadata into the WASM module # -O — output directory faust -lang wasm \ -cn "$NAME" \ -e \ -O "$SCRIPT_DIR" \ "$DSP" \ -o "$SCRIPT_DIR/${NAME}.wasm" # Step 2: emit the standalone JSON descriptor (separate pass so the JSON # is always present even if the WASM glue is regenerated). # -json produces .json next to the source. faust -json "$DSP" -o /dev/null 2>/dev/null || \ faust -lang codebox -json "$DSP" -o /dev/null 2>/dev/null || true # Faust places the JSON next to the .dsp; rename to sit next to outputs. if [ -f "${DSP}.json" ]; then mv "${DSP}.json" "$SCRIPT_DIR/${NAME}.json" elif [ -f "$SCRIPT_DIR/${NAME}.json" ]; then : # already in the right place (some faust versions) else echo " WARNING: ${NAME}.json not produced — check faust version" fi if [ -f "$SCRIPT_DIR/${NAME}.wasm" ]; then WASM_SIZE="$(du -h "$SCRIPT_DIR/${NAME}.wasm" | cut -f1)" echo " -> ${NAME}.wasm (${WASM_SIZE})" fi if [ -f "$SCRIPT_DIR/${NAME}.json" ]; then echo " -> ${NAME}.json" fi done echo "" echo "Done. Load engines in the playground via FaustEngineBase:" echo " import { AdditiveEngine } from './js/synth/additive-engine.js';"