v1.33.0

kevinraymond/fosforav1.33.0Aug 12, 2026by github-actions[bot]

AI Summary

Major overhaul of audio analysis features, rebranding from Phosphor to Fosfora, and adding headless analysis and loop export capabilities.

Key Highlights

  • Phosphor rebranded to Fosfora with config directory migration and OSC namespace changes.
  • New Ableton Link build option for beat-syncing with other devices.
  • New headless analysis mode (`--signal`) broadcasts analysis data via OSC.
  • New `--render-loop` command for seamless beat-locked exports.
  • Significant improvements to section detection, key detection, and beat tracking accuracy.

Breaking Changes

  • Config directory moves to 'fosfora' on first launch.
  • OSC namespace changes from `/phosphor/` to `/fosfora/`.
  • `audio.section_novelty` normalization behavior changed.
  • Key detection accuracy changes (0.317 -> 0.520 MIREX-weighted).
  • Beat tracking logic rebuilt to phase-lock grid.

New Features

  • Ableton Link support
  • Headless signal broadcasting
  • Seamless beat-locked loop export
  • New `/fosfora/v1/section/boundary` Signal address

Full Release Notes


### Added
- **New `/fosfora/v1/section/boundary` Signal address** fires whenever the music changes
  material, carrying a confidence and the boundary's age in seconds. `/section` only ever
  spoke when its label changed, so a chorus following a verse was silent; this one is not.
  Gate on the confidence if false cues are costly — the top third of events are right about
  66% of the time against 38% for the bottom third.

### Changed
- **Section boundaries are actually detected now.** The self-similarity novelty had been
  computed and published for four releases without anything ever thresholding it, so the
  section stream announced 3.7 boundaries on a track averaging 12.3 — boundary accuracy
  0.105 → 0.503 on 374 Harmonix tracks, at 12.1 boundaries per track. Cues land about 6 s
  after the boundary they describe, and each event says so.
- **`audio.section_novelty` no longer sits pinned at 1.0.** It was normalized against its own
  recent maximum, so unchanging music drove it to full scale — the opposite of what the name
  promises. It now reads near zero on steady material and rises only on real change. Anything
  bound to it will read lower and move more; rescale that binding if it looked right before.
- **Key detection now hears the actual key on EDM.** It used to name an unrelated
  key more than half the time — quiet noise frames voted as loudly as drops, the
  chroma template manufactured subdominant energy, and the loudest content in the
  genre (kick and sub-bass) was either invisible or misread. The key path now
  energy-weights a clean fold and tracks the sub-bass root directly: 0.317 → 0.520
  MIREX-weighted on 604 GiantSteps EDM tracks, exact keys 153 → 272. Key readouts
  and key-driven palettes settle in about 3 s.
- **Beat and tempo tracking rebuilt.** Beats fired on every loud onset whenever tempo
  confidence dipped — 1.5-1.7× too many, spraying beat-bound strobes — and drifted
  100+ ms late on misses; they now fire on a phase-locked grid (within ~10 ms on
  synthetic kicks) and go quiet through breakdowns instead of spraying. The detected
  tempo also commits to its level: double-kick and half-time-feel material no longer
  flips the readout between 172/115/86-style relatives mid-track, and the BPM value
  holds through breakdowns instead of blanking. EDM tempo accuracy rose 0.60 → 0.70
  (past offline madmom), tempi between analysis bins like 175 BPM became representable
  at all, and hard-stuck octave errors clear. Tracks now stay silent for the first few
  seconds until the tempo locks; `/onset` and the kick stem keep firing throughout.
- **Phosphor is now Fosfora, everywhere.** Your config directory moves over automatically
  on first launch (settings, presets, scenes and mappings all come along), OSC output now
  uses `/fosfora/...` — incoming `/phosphor/...` is still accepted, and a legacy TX
  namespace option in the OSC panel keeps old rigs fed — and the from-source binary is
  `fosfora` (downloads were already named that). macOS asks for microphone permission once
  more (new bundle id); debug env vars are now `FOSFORA_*`. Custom shaders calling
  `phosphor_*` helpers keep working via deprecated aliases.

### Added
- **Ableton Link (build option).** Build with `--features link` and Fosfora joins your
  Link session: Follow mode locks the beat tracker's tempo to the session (beat phase
  still tracks the audio it hears), Lead mode pushes Fosfora's detected BPM to your
  other gear once it holds steady, and beat-synced scene advance rides the shared
  session grid. Works in `--signal` headless mode too (`/fosfora/v1/link/*`). Absent
  from the prebuilt downloads — Ableton Link is GPL-licensed, so it's a from-source
  option. Enable it in Settings → Ableton Link.
- **Signal: headless analysis broadcast.** `fosfora --signal` runs the analysis engine
  with no window or GPU and broadcasts what it hears over versioned OSC
  (`/fosfora/v1/...`): beats and bars the hop they fire, BPM, key, build level,
  section labels (intro/build/drop/break/steady), phrase position on an inferred
  8/16/32-bar grid, and a `predict/drop` confidence that rises *before* the likely
  drop — lead time for the operator, with a confidence value on every stateful
  address. `--signal-dump song.flac` writes the same stream to a JSONL file,
  deterministically. See docs/SIGNAL.md.
- **Seamless beat-locked loop export.** `--render-loop <spec.loop.json>` renders any
  phase-locked overlay to a mathematically seamless loop file — HAP, HAP Alpha (real
  transparency for Resolume/VJ software), ProRes 4444, H.264/HEVC — with beat/bar motion
  synthesized at an exact tempo (requested BPM snaps to the nearest frame-perfect one and
  both are reported). Non-loopable effects get explicit best-effort escapes
  (`--allow-non-loop`, `--crossfade-bars` with warmup). One CLI call replaces the After
  Effects loop-compositing grind; needs ffmpeg on PATH. See docs/loop-export.md.

### Fixed
- **Intarsia filled the screen with tiles, then blanked and started over every few
  bars.** Tiles now trade in and out individually on the bar clock, holding a steady
  mosaic with no reset. A new `density` param sets how much of the mosaic is lit at
  once; `bars_per_cycle` is now the turnover period — how often each tile trades.
- **A mistyped or unsupported command-line flag silently launched the full app** —
  window, GPU and all. Unknown flags now print an error and exit, `--help` and
  `--version` work, and a flag needing a build feature you don't have (like
  `--signal-dump` without `--features analyze`) says so by name. New `--caps` prints
  the features a binary was built with.

## Downloads

| Platform | File | Notes |
|----------|------|-------|
| **macOS** | `.dmg` | Universal binary (Apple Silicon + Intel) |
| **Linux x86_64** | `.tar.gz` | glibc 2.35+ (Ubuntu 22.04+, Debian 12+) |
| **Windows x64** | `.zip` | Windows 10+ |

## Getting started

**macOS**: Open the DMG, drag Fosfora.app to Applications (or run directly). Signed and notarized.

**Linux / Windows**: Extract, run `fosfora` from the extracted directory. The `assets/` folder must be next to the binary.

## Requirements

- **GPU**: Vulkan (Linux/Windows) or Metal (macOS)
- **Audio**: Built-in mic or line-in for audio-reactive visuals
- **NDI®** (optional): [NDI® SDK runtime](https://ndi.video) for network video output
- **Video playback** (optional): `ffmpeg` on PATH for media layers

---
NDI® is a registered trademark of Vizrt NDI AB.