v1.7.1
Fixed
- Binding matrix button — clicking the "Matrix" button in the left panel now correctly opens the binding matrix (previously opened for one frame then immediately closed due to same-frame click-outside detection)
- Status bar hint — added
B binding matrixkeyboard hint to the status bar
Added
- Cargo.toml metadata — added
description,repository,readme,publishfields to member crate - CI format check — added
cargo fmt --all -- --checkjob to CI workflow - Dependency auditing — added
deny.tomlandcargo-denyCI job for license compliance and vulnerability scanning - Direct video recording — record Phosphor output directly to MP4/MKV via FFmpeg subprocess with NVENC hardware encoding (auto-fallback to CPU encoders). Supports H.264, HEVC, and AV1 codecs up to 8K resolution at 30/60 FPS with configurable CQ quality. Includes audio capture from the active audio input (muxed as AAC via named FIFO). Recording runs independently alongside NDI output. New "Outputs" subsection in Settings panel with record button, codec/resolution/FPS/quality/audio controls, and live status display (duration, file size, encoder info). No new crate dependencies — uses the same subprocess pattern as the FFmpeg webcam backend.
- Shared FrameCapture — extracted double-buffered GPU readback from
NdiCaptureintogpu::frame_capture::FrameCapture, reused by both NDI and recording systems - OutputResolution::Res8K — 7680x4320 output resolution option for both NDI and recording
- OutputResolution moved to
gpu::types— shared by NDI and recording modules (NDI re-exports for backwards compatibility)
Changed
- Background shader compilation — shader hot-reload (fragment + compute) now compiles on a dedicated background thread instead of blocking the main render loop. Eliminates 50-500ms frame hitches when saving
.wgslfiles during development. Old pipeline continues rendering while the new one compiles; swap is atomic on completion. - Error handling sweep — replaced all runtime
.unwrap()calls with.expect("reason")documenting invariants (mutex locks, container access, thread spawns). Added// SAFETY:comments to all 22 unsafe blocks across FFI bindings (WASAPI, PulseAudio, JACK, NDI, ALSA) and internal unsafe code (ring buffer, pipeline cache). Enabledclippy::undocumented_unsafe_blockslint to prevent future regressions. - Idiomatic Rust pass — eliminated per-frame allocations and unnecessary clones across the hot path:
ParamStore::split_borrow()for disjoint field access (removes 3×defs.clone()per frame in MIDI/OSC/WS update paths)PlaybackStatenow derivesCopy(removesstate.clone()per frame in timeline tick)- Binding bus: snapshot moved instead of cloned;
HashMap::get_mutfast-path for runtime lookup (avoidsbinding.id.clone()per enabled binding per frame) - Match on
&ParamDef/&TransformDefreferences instead of cloning owned values - PFX hot-reload:
new_effectmoved instead of cloned;old_effectborrow replaces full clone - Shader hot-reload: effect borrowed from loader instead of cloned
- Added
#[derive(Debug)]toBindingRuntime,LearnState,BindingTemplate,TemplateEntry,NdiFrame,PresetDecodeRequest,DepthFrame;Default+CloneonBindingRuntime builtin_raster_images()returns&'static [String]instead of&'static Vec<String>- MIDI panel: port selection deferred to after iteration (avoids
available_ports.clone())
Fixed
- Accretion drift -- N-body simulation no longer drifts off-screen over time. Nonlinear centering force (gentle at origin, strong near edges), center-biased seed spawning, and tighter boundary kill prevent compounding center-of-mass shift
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 Phosphor.app to Applications (or run directly). Signed and notarized.
Linux / Windows: Extract, run phosphor 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 for network video output
- Video playback (optional):
ffmpegon PATH for media layers
NDI® is a registered trademark of Vizrt NDI AB.