Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
name: CI
on: [push, pull_request]
on:
push:
branches: [master]
pull_request:

env:
CARGO_TERM_COLOR: always

jobs:
check:
runs-on: ubuntu-latest
test:
name: Test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: sudo apt-get install -y libasound2-dev
- run: cargo check
- uses: Swatinem/rust-cache@v2
- name: Install Linux audio/GUI libraries
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y pkg-config libasound2-dev libjack-jackd2-dev \
libx11-dev libx11-xcb-dev libxcb1-dev libxcb-icccm4-dev libxcb-dri2-0-dev \
libxcursor-dev libxrandr-dev libxi-dev libxkbcommon-dev libgl1-mesa-dev libudev-dev
- name: Build (app + plugin)
run: cargo build --workspace --locked
- name: Test
run: cargo test --workspace --locked
132 changes: 132 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
name: Release

# Push a tag like v1.4.0 to build the desktop app for Linux, macOS and Windows
# and attach it to a GitHub Release. Publishing to crates.io stays manual.
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
# Build-only dry run when this workflow itself changes (nothing is released).
pull_request:
paths:
- ".github/workflows/release.yml"
workflow_dispatch:
inputs:
tag:
description: "Existing tag to (re)build, e.g. v1.4.0"
required: true

permissions:
contents: write

env:
CARGO_TERM_COLOR: always
TAG: ${{ github.event_name == 'pull_request' && 'pr-test' || github.event.inputs.tag || github.ref_name }}

jobs:
build:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
- os: macos-latest
target: aarch64-apple-darwin
- os: macos-latest
target: x86_64-apple-darwin
- os: windows-latest
target: x86_64-pc-windows-msvc
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'pull_request' && github.sha || env.TAG }}

- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}

- name: Install Linux audio/GUI libraries
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y pkg-config libasound2-dev libjack-jackd2-dev \
libx11-dev libx11-xcb-dev libxcb1-dev libxcb-icccm4-dev libxcb-dri2-0-dev \
libxcursor-dev libxrandr-dev libxi-dev libxkbcommon-dev libgl1-mesa-dev libudev-dev

- name: Build
run: cargo build --release --locked -p math-sonify --bin math-sonify --target ${{ matrix.target }}

- name: Package (Unix)
if: runner.os != 'Windows'
shell: bash
run: |
name="math-sonify-${TAG}-${{ matrix.target }}"
mkdir "$name"
cp "target/${{ matrix.target }}/release/math-sonify" README.md LICENSE config.toml "$name/"
tar czf "$name.tar.gz" "$name"
shasum -a 256 "$name.tar.gz" > "$name.tar.gz.sha256"

- name: Package (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$name = "math-sonify-$env:TAG-${{ matrix.target }}"
New-Item -ItemType Directory $name | Out-Null
Copy-Item "target/${{ matrix.target }}/release/math-sonify.exe", README.md, LICENSE, config.toml $name
Compress-Archive -Path $name -DestinationPath "$name.zip"
$hash = (Get-FileHash "$name.zip" -Algorithm SHA256).Hash.ToLower()
"$hash $name.zip" | Out-File -Encoding ascii "$name.zip.sha256"

- name: Smoke test
shell: bash
run: |
bin="target/${{ matrix.target }}/release/math-sonify"
if [ "${{ matrix.target }}" = "x86_64-apple-darwin" ]; then exit 0; fi
"$bin" --version
"$bin" --help

- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}
path: |
math-sonify-*.tar.gz*
math-sonify-*.zip*

release:
name: Publish GitHub Release
needs: build
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true

- name: Checksums
run: |
cd dist
cat *.sha256 > SHA256SUMS.txt
cat SHA256SUMS.txt

- name: Create or update release
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: |
ls -l dist
notes="Prebuilt math-sonify desktop app for Windows, macOS (Apple Silicon and Intel) and Linux.

Pick the file for your system: \`*-x86_64-pc-windows-msvc.zip\` (Windows), \`*-aarch64-apple-darwin.tar.gz\` (Apple Silicon Mac), \`*-x86_64-apple-darwin.tar.gz\` (Intel Mac), \`*-x86_64-unknown-linux-gnu.tar.gz\` (Linux). The binaries are unsigned, so Windows SmartScreen may warn about an unknown publisher (More info, then Run anyway) and macOS may need right-click, Open. Run with \`--help\` for the headless WAV renderer. See CHANGELOG.md for what changed."
if gh release view "$TAG" >/dev/null 2>&1; then
gh release upload "$TAG" dist/* --clobber
else
gh release create "$TAG" dist/* --title "math-sonify $TAG" --notes "$notes"
fi
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# Math Sonify — Changelog

## [1.4.0] - 2026-09-25

### Added

- Prebuilt downloads: a release workflow builds the desktop app for Windows (x86_64),
macOS (Apple Silicon and Intel) and Linux (x86_64) on every `v*` tag and attaches
them, with `SHA256SUMS.txt`, to the GitHub Release.
- `--help` and `--version` flags.
- `cargo install math-sonify` support: the VST3/CLAP plugin moved into its own
unpublished workspace crate (`plugin/`) because nih-plug is not on crates.io.

### Changed

- The core library is now `math_sonify` (`src/lib.rs`); the plugin crate builds
`math_sonify_plugin` with `cargo build --release -p math-sonify-plugin`.
- CI builds and tests the whole workspace on Linux, Windows and macOS and installs the
Linux audio and windowing libraries it needs.

### Fixed

- Test suite compiles again (`evolution` and `preset_gallery` tests).
- `collab`: `set` messages dropped their last parameter because the parser matched the
outer closing brace.
- `beat_tracker`: tempo estimation always returned 60 BPM; it now picks the dominant
inter-onset interval.
- `randomizer`: the chaos check ran too briefly for any Lorenz trajectory to pass.
- Broken doc examples in `audio_driven` and `duffing`, and four tests with wrong
expectations (arpeggiator LFO, DC blocker, spectrum DC bin, Rule 90 symmetry).

## [Unreleased] — Production-ready pass (2026-03-18)

### Fixed
Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ src/
├── ui.rs # egui UI, AppState
├── arrangement.rs # Scene/arrangement interpolation
├── presets.rs # Preset application helpers
├── plugin.rs # nih-plug VST3/CLAP wrapper
├── lib.rs # core library (shared by app and plugin)
├── systems/ # Dynamical systems
│ ├── mod.rs # DynamicalSystem trait, rk4/rk45 helpers, re-exports
│ ├── lorenz.rs
Expand Down Expand Up @@ -194,13 +194,13 @@ The binary is at `target/release/math-sonify[.exe]`. Copy alongside `config.toml
### VST3 / CLAP plugin

```sh
cargo build --lib --release
cargo build --release -p math-sonify-plugin
```

The compiled `.dll` / `.so` / `.dylib` is the plugin binary. Use [cargo-nih-plug](https://github.com/robbert-vdh/nih-plug) or nih-plug's own bundler for proper VST3/CLAP bundle layout:

```sh
cargo xtask bundle math_sonify_plugin --release
cargo xtask bundle math_sonify --release
```

### Development build
Expand Down
Loading
Loading