We built mastacraf, a command-line audio mastering pipeline written in Rust and powered by FFmpeg.
The project is designed for self-produced experimental music where I do not necessarily want a tool making aesthetic decisions for me. I want something more direct:
- analyze the file
- apply a preset-defined processing chain
- write the mastered output
- generate waveform/spectrogram visuals
- save a JSON report showing exactly what happened
Repo: https://github.com/schwwaaa/mastacraf
Docs: https://schwwaaa.github.io/mastacraf/
Bandcamp: https://cskonopka.bandcamp.com/album/friend
Why this exists
A lot of mastering workflows are either plugin-heavy or too opaque.
That is fine for some situations, but I wanted something local, repeatable, and inspectable.
For experimental music, the goal is not always “make this commercially loud.” A noise piece, drone, abstract electronic track, or film cue may each need different loudness targets and dynamics behavior.
mastacraf is built around presets so the tool does not decide the aesthetic. The preset defines the choice.
What it does
The current pipeline is intentionally linear:
analyze() → visualize(pre) → process() → visualize(post) → report()
For each mastered track, mastacraf can generate:
mastered/
track/
track_master.wav
track_pre_spectrogram.png
track_pre_waveform.png
track_post_spectrogram.png
track_post_waveform.png
track_compare_spectrogram.png
track_compare_waveform.png
track_diff_spectrogram.png
track_diff_waveform.png
track_master_report.json
The JSON report includes the pre/post measurements, preset settings, deltas, and the exact FFmpeg filter chain.
That means the master is not just an exported file. It is reproducible.
Install
You need Rust and FFmpeg.
macOS:
brew install ffmpeg rust
Ubuntu / Debian:
sudo apt install ffmpeg
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Build:
git clone https://github.com/schwwaaa/mastacraf.git
cd mastacraf
cargo build --release
Binary:
./target/release/mastacraf
Analyze first
The most important workflow rule is:
mastacraf analyze track.wav
This prints measurements without writing mastered audio.
mastacraf measures:
- integrated LUFS
- true peak
- loudness range
- RMS
- crest factor
- dynamic range
- DC offset
- phase correlation
- spectral balance
- spectral centroid
Those values help decide what a preset should do.
For example:
- Low or negative phase correlation is probably a mix problem.
- Very high crest factor means the limiter attack should probably be slower.
- If measured LRA is high, setting a low LRA target can collapse dynamics.
- If the file is already near the true peak ceiling, the limiter may work harder than expected.
The point is to make mastering decisions from measurements instead of guessing.
Master a file
Basic usage:
mastacraf master track.wav
Use a preset:
mastacraf master track.wav --preset noise
Use a custom output folder:
mastacraf master track.wav --preset film --output ./deliverables/
Override loudness values:
mastacraf master track.wav --lufs -18 --true-peak -0.5
Dry run:
mastacraf master track.wav --preset mypreset --dry-run
Verbose mode:
mastacraf master track.wav --preset mypreset --verbose
Verbose mode prints the FFmpeg commands, which is useful because the tool is meant to be transparent.
Presets
Presets are TOML files.
The included presets are currently aimed at different use cases:
default → general experimental / abstract
noise → harsh noise / power electronics
film → film scoring / cinematic / broadcast
A normal workflow looks like this:
mastacraf analyze track.wav
cp presets/default.toml presets/mypreset.toml
mastacraf master track.wav -p mypreset --dry-run
mastacraf master track.wav -p mypreset
A preset can control:
- LUFS target
- true peak ceiling
- loudness range
- high-pass / low-pass filtering
- optional compression
- limiter behavior
- output format
- bit depth
- sample rate
- visualization settings
The key design decision is that every audio-affecting setting should be visible.
No hidden processing.
FFmpeg filter chain
Internally, the processing chain is a standard FFmpeg audio filter string.
The structure is:
highpass → lowpass → compressor → limiter → loudnorm
Disabled stages are omitted.
The exact filter chain is stored in the report, so you can inspect or reproduce it later.
Example idea:
ffmpeg -i input.wav -af "<filter_chain>" -acodec pcm_s24le -ar 44100 output.wav
Rust is useful here because it gives the project a clean CLI structure around FFmpeg without needing to reimplement DSP.
Visual reports
mastacraf can generate before/after waveform and spectrogram images.
This is useful for checking whether the mastering stage changed the file in the way you expected.
For example:
- Did the waveform envelope stay mostly intact?
- Did the limiter only catch isolated peaks?
- Did the spectrogram change uniformly, or did specific bands change?
- Did loudnorm mostly apply clean gain?
The visuals are not a replacement for listening, but they are helpful review artifacts.
Why Rust + FFmpeg works well here
Rust is handling:
- CLI arguments
- config and preset loading
- file organization
- pipeline orchestration
- report generation
FFmpeg is handling:
- decoding
- loudness analysis
- filtering
- limiting
- visualization
- output encoding
That split keeps the project small and practical.
I am not trying to build an audio engine from scratch. I am wrapping a reliable media tool in a repeatable workflow.
Future paths
The project is still early, but the structure leaves room for:
- more filter stages
- custom EQ presets
- AI/ONNX preprocessing
- matchering pre-pass workflows
- demucs/source-separation inspection
- Tauri desktop wrapper
The current version is deliberately focused:
analyze → process → visualize → report
That is the useful core.
Takeaway
mastacraf is not a “magic mastering” tool.
It is a repeatable mastering workflow for people who want to define their own targets and keep the process visible.
That matters for experimental music because the right answer is not always the loudest or most standardized master.
Sometimes the right answer is the one you can explain, inspect, and reproduce.
Repo: https://github.com/schwwaaa/mastacraf
Docs: https://schwwaaa.github.io/mastacraf/
Bandcamp: https://cskonopka.bandcamp.com/album/friend


Top comments (0)