The monitor ring fed raw input-device samples to the output callback as if
they were at the session rate. A 16 kHz or 44.1 kHz input played back too
fast (higher pitch) and ran dry between bursts, so it sounded quiet.
InputRing now knows the input rate and converts to the session rate with
linear interpolation in pop_into, allocation-free and non-blocking. The
buffer cap is computed once in new(). Tests cover rate up-conversion,
down-conversion, equal rates and underrun.
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Options > Click set a flag but nothing rendered sound, so a click track
was silent. The mix engine now synthesizes a short blip on every beat of
the tempo map (accent on beat 1), using the click.* settings from
Setup > Click/Countoff, and sums it after the master fader.
The metronome is opt-in per engine: only live playback enables it.
Offline renders (bounces, stems, exports) leave it off so the click is
never printed into a file.
Also: midi_to_hz moves from the engine demo into soundcraft-dsp so the
mix and demo share one tuning formula.
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
The desktop app installed no logger, so every log::warn!/log::error! in
the workspace was discarded: the engine's panic report, audio devices
that failed to open or broke, plugins that refused their stored state or
failed to activate, CLAP plugins' own log messages, files that failed to
open. A launch from a desktop menu has no terminal either, so there was
nothing to attach to a bug report.
apps/soundcraft/src/logging.rs (no new dependency):
- standard error plus <settings dir>/logs/soundcraft.log (beside
ui.json, Autosave/ and Presets/); each launch rotates the previous log
to soundcraft.1.log and .2.log, so the log of a run that crashed
survives the next start; the file is capped at 16 MiB
- records logged before the settings directory is known are buffered
(bounded) and written once the file is attached
- default levels: info for soundcraft*, warn for everything else;
RUST_LOG replaces them with env_logger-style directives
- never panics: an unusable directory or a failed write leaves standard
error as the only sink; a poisoned lock is tolerated
- runs with SOUNDCRAFT_NO_PREFS (agents' test runs) log to standard
error only, so they don't rotate away the user's own logs
Realtime audio: a record takes a lock and does I/O, which the audio
callback must never do, yet code on the audio thread logs (the cpal
error callbacks, the synth's full event queue, a hosted plugin's failed
process, a CLAP plugin calling the host's log, the panic hook). The cpal
callbacks now mark their thread (soundcraft_mix::mark_audio_thread,
re-exported by soundcraft_playback), and the mix engine carries the mark
into the rayon workers that render strips for it. A record from a marked
thread is not written there: the first is kept in a fixed buffer
(try_lock, no allocation, never waits), the rest are counted, and the UI
thread writes them every frame (any other thread before its own next
record).
The logger is installed first in main (before the engine's panic hook)
and the file is opened after argument parsing (--version leaves no
file). The settings directory moves out of prefs_path into config_dir.
The control server's eprintln!s go through the logger (the
SOUNDCRAFT_CONTROL_PORT line on standard output stays). Documented in
README.md (Getting started > Logs) and docs/architecture.md (Audio).
Video (new standalone crate soundcraft-video):
- Pure-Rust H.264 (Baseline/Main/High), ProRes (all flavours) and Motion JPEG decoding with
ISO-BMFF demux, adapted from FilmCraft's crates; fuzzed with mutated/truncated movies
- TrackKind::Video with ClipContent::Video referencing Session.videos; file.import_video adds
the picture track and the movie's audio; relinking on open; video.offset/online/list
- Video and Video Universe windows, thumbnails on the timeline, background decoding
Third-party plugins:
- Plugin state (CLAP state ext, VST3 component + controller state) saved in sessions
- Hosted instances created, state-loaded and dropped on the UI thread, never the audio thread
- Plugin editors: floating CLAP GUIs and VST3 views on macOS (verified with Melodyne)
- New isolated FFI crate soundcraft-au-host: Audio Units on macOS (effects and instruments,
parameters, latency, MIDI, ClassInfo state), wired into the mixer and plugin browser
UI: Window > Renderer (speaker layout with live levels and object positions), Window > UI
Customization (interface scale, reduce motion), Window > Configurations > Auto-Update.
Fix: saturating sample-index math in clip rendering (hostile stretch values overflowed).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Surround:
- main and bus formats up to 9.1.6 and Ambisonics; pairwise constant-power
surround panner (divergence, centre, LFE, height) per track and send;
ITU fold-down; multichannel bounce with correct WAV channel masks;
multichannel device output; surround panner and multichannel meters in the
Mix window; setup.main_format, mix.surround_pan, mix.send_surround_pan
VST3:
- soundcraft-vst3-host: isolated unsafe crate (vst3 bindings, MIT), scans
standard folders, hosts components/processors/controllers, params,
latency, notes; VST3 menu; engine.vst3_plugins; e2e tests with a fixture
Hardening:
- positions from parameters clamped; offline renders capped and bounded to
track material; loop/transport limits; hostile-parameter property test
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- mix: per-strip insert latency, delay lines align all tracks to the slowest
and direct outputs to aux returns; offline renders remove the latency
- input monitoring: live input (InputRing from the recorder) replaces clips
on monitored tracks and on armed tracks when stopped or recording, through
the full channel strip; the player renders while stopped for monitoring
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Workspace for SoundCraft, a clean-room pure-Rust Pro Tools-class DAW:
timebases and tempo maps, WAV/AIFF/FLAC/symphonia audio IO with peaks,
SMF and MIDI ops, 26 original DSP plugins, the session model, the mix
engine, ~180 registered commands with undo, a cpal player, and the
agent rules (AGENTS.md, ATTRIBUTION.md).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>