denoize
The pursuit of the world's highest-fidelity audio denoising — in pure Rust.
denoize removes background noise from WAV recordings with maximum transparency:
preserving timbre, transients, dynamics, stereo imaging, and natural "air".
Implemented technology stack
Classical DSP (always available)
- STFT/ISTFT + Perfect Reconstruction OLA + high overlap
- IMCRA/MCRA noise estimation + SPP + spectral-flatness profiling
- Ephraim-Malah Decision-Directed SNR
- 8 gain estimators: OMLSA, LogMMSE, MMSE-STSA, Wiener, SpecSub, SpecSub-NL, SpecSub-Geo
- Transient protection, cepstral smoothing, pre-emphasis
- Advanced windows: Kaiser, Flat-top, DPSS (+ Hann/Hamming/Sine/Blackman)
- Multiband spectral subtraction (Bark bands)
- Perceptual weighting (Bark-scale gain shaping)
- Musical-noise post-filter
Optional AI backends (feature-gated)
| Backend | Feature | Description |
|---|---|---|
rnnoise |
--features rnnoise |
RNNoise via nnnoiseless (pure-Rust) |
deepfilter |
--features deepfilter |
DeepFilterNet v3 (tract ONNX, embedded model) |
onnx |
--features onnx |
External waveform-to-waveform ONNX model (tract, Pure Rust) |
mpsenet |
--features mpsenet |
MP-SENet magnitude/phase enhancement adapter (external converted model) |
bsrnn |
--features bsrnn |
ESPnet BSRNN spectral enhancement adapter (external converted model) |
mossformer2 |
--features mossformer2 |
ClearerVoice MossFormer2 48 kHz mask adapter (external converted model) |
sgmse |
--features sgmse |
SGMSE+ iterative diffusion adapter (external converted model) |
gtcrn |
--features gtcrn |
Official 48K-parameter causal GTCRN; offline and stateful streaming |
Build everything: cargo build --release --features full
The generic ONNX backend is the deployment foundation for future neural models. It intentionally accepts only single-input/single-output waveform models; spectral models and diffusion samplers require dedicated adapters.
The prebuilt GitHub binaries include every backend. Because DeepFilterNet 0.5.6 is not available from crates.io, the crates.io package's
fullfeature currently includes RNNoise, generic ONNX, MP-SENet, BSRNN, MossFormer2, and SGMSE+, but not DeepFilterNet.
Supported input formats
| Format | Decoder | Notes |
|---|---|---|
| WAV/BWF | hound |
8–32 bit int / float; BWF metadata chunks are preserved for supported tags |
| RF64 | native RF64 reader | 64-bit-size PCM/WAVE, bounded chunk reads |
| AIFF/AIFC | symphonia |
PCM and supported AIFC codecs |
| CAF | symphonia |
PCM and ALAC/other supported CAF codecs |
| MP3 | nanomp3 (Pure Rust) |
ID3 skip, no resampling |
| M4A/AAC/ALAC | oxideav-aac + symphonia fallback |
MP4 demux + AAC-LC/ALAC decode |
| FLAC | claxon |
Lossless FLAC |
| Ogg Opus/Vorbis | opus + ogg / symphonia |
Mono/stereo; native sample rate decode |
Output formats
| Format | Encoder | Notes |
|---|---|---|
| WAV | hound |
Lossless; preserves bit depth |
| MP3 | shine-rs (Pure Rust) |
--mp3-bitrate (default 192 kbps) |
| M4A | oxideav-aac + MP4 mux |
GitHub/source builds; --m4a-bitrate (default 192 kbps) |
| FLAC | flacenc |
Lossless, pure Rust |
| Ogg Opus | opus + ogg |
128 kbps, mono/stereo |
Channel order is kept planar and unchanged through WAV/FLAC and denoising. The
standard layouts mono, stereo, 2.1, quad, 5.0, 5.1, 6.1, and 7.1 are reported
when their channel count is recognized. MP3, M4A, and ADTS AAC encoders in the
current release accept only mono/stereo; surround input is rejected instead of
being mixed implicitly. Use --downmix stereo when a documented, explicit
surround-to-stereo render is intended (LFE is not copied into the full-range
stereo pair). WAVE_FORMAT_EXTENSIBLE speaker masks are read, preserved, and
written for multichannel WAV files; --report also shows each channel's
azimuth/elevation pan coordinate. A non-standard but valid mask is used for
position-aware downmixing instead of being guessed from the channel count.
Stereo processing can be selected with --channels mid-side. This uses a
reversible, energy-preserving Mid/Side transform (M=(L+R)/sqrt(2),
S=(L-R)/sqrt(2)) and reconstructs the original channel order and speaker
metadata after denoising.
# MP3 / M4A input and output — no manual ffmpeg conversion
# User-supplied waveform model: [1, samples] or [1, 1, samples]
# Official MP-SENet checkpoint converted with scripts/export-mpsenet.py
# ESPnet BSRNN xtiny checkpoint converted with scripts/export-bsrnn.py
# ClearerVoice MossFormer2 48 kHz model
# Official SGMSE+ VoiceBank model (30-step quality sampler)
# Verified official GTCRN model (manual model path is unnecessary afterwards)
# Stereo coupling, pipes, metrics, and directory batches
|
To prepare the pinned official MP-SENet VoiceBank model:
The VoiceBank graph is about 9 MiB and expects 16 kHz audio. On the reference x86-64 Linux host, a two-second mono speech fixture took 43.67 seconds after model loading and the complete process used 410,048 KiB maximum RSS. Run the pinned real-speech quality gate after conversion:
To prepare the pinned ESPnet BSRNN xtiny model (CC-BY-4.0):
|
The adapter resamples to 48 kHz and reproduces the published model's variance normalization, centered 960-point Hann STFT with a 480-sample hop, whole-utterance recurrent inference, and inverse STFT. The converted model is about 2.4 MiB. On a release build on the project reference x86-64 Linux host, the fixed two-second regression fixture took 1.58 seconds (1.3x realtime) and used 44,628 KiB maximum RSS. Runtime and memory grow with utterance length.
Run the reproducible real-speech quality gate after conversion:
To prepare the pinned Apache-2.0 MossFormer2 SE 48 kHz model:
|
The adapter uses 48 kHz audio, 40 ms Kaldi fbank frames at an 8 ms shift, first- and second-order deltas, a non-centred 1,920-point symmetric-Hamming STFT, and the official four-second/three-second-stride edge-discard reconstruction. The converted graph is about 217 MiB. On the reference x86-64 Linux host, a four-second mono fixture took 7.74 seconds and used 483,400 KiB maximum RSS in a release build. Model weights are not bundled.
Run the pinned real-speech quality gate after conversion:
To prepare the pinned MIT-licensed SGMSE+ VoiceBank+DEMAND model:
|
The adapter reproduces the official noisy-peak normalization, centered
510-point periodic-Hann STFT with a 128-sample hop, complex square-root
spectrum transform, and OUVE predictor/corrector sampler. The explicit
quality/speed choice is the upstream 30 reverse steps with one ALD corrector
step (snr=0.5), or 60 score-network evaluations. The graph is about 252 MiB
and weights are not bundled. On the reference x86-64 Linux host, the pinned
two-second mono fixture took 737.92 seconds and used 1,204,648 KiB maximum RSS
in a release build. This backend prioritizes generative quality rather than
interactive speed.
Run the pinned quality gate after conversion (expect a long CPU run):
Quick start
# Best classical quality
# RNNoise AI backend
# DeepFilterNet v3 AI backend
# Advanced DSP options
Long recordings with bounded memory
For long WAV recordings, use the classical streaming path. It keeps only the STFT overlap and a fixed-size input block in memory instead of loading the whole file:
--stream currently supports filesystem WAV-to-WAV processing with the
classical backend and independent channels. VAD, loudness normalization,
mid/side or linked stereo processing, and AI/encoded output require the normal
(non-streaming) path. The default block size is 8192 frames; use
--stream-frames N to trade latency and working memory for throughput. Noise
profiling retains only a bounded leading segment before output begins.
For the normal (decoded, non-streaming) path, --max-memory MB performs a
conservative preflight and decoded-working-set check before processing. The
limit is per input file/worker; batch jobs can use memory concurrently, so
lower --jobs when enforcing a process-wide budget. A streaming WAV job stays
bounded by its block size and denoiser state, and the same option checks that
bound:
Desktop app
The Tauri desktop app exposes single-file denoising, batch conversion, quality
comparison, and model management without sending audio off the computer. Its
default build includes every backend in the repository's full feature set;
FDK-AAC remains an explicit opt-in because of its separate licensing terms.
ONNX-based backends expose model-file, model-rate, and SGMSE quality controls
when selected; managed GTCRN weights are resolved automatically after install.
Desktop batches accept files or folders, preserve relative paths, run with a
configurable worker count, continue after individual failures, and can resume
from the .denoize-gui-state journal in the output directory.
Single-file processing also provides local waveform previews, RMS-matched
before/after switching, click-to-seek, and configurable section looping.
Desktop settings are restored automatically, can be stored as named presets,
and can be imported or exported as CLI-compatible TOML. Recent input files are
kept locally for quick reuse. The single-file and batch views also expose a
reproducibility mode that serializes processing and uses stable model seeds.
Audio files and folders can be dropped onto the single-file or batch input
zones; output folders have dedicated drop targets. Multiple audio files switch
the app to batch mode automatically.
The realtime page routes a selected capture device through a low-latency
backend to a playback device, with input/output meters, dropped-chunk counters,
and explicit start/stop controls. Headphones help prevent acoustic feedback.
# Build a platform-native installer/package
# Optional FDK-AAC selector
Linux development requires the WebKitGTK 4.1 and GTK 3 development packages. For Ubuntu 24.04 or later:
Prebuilt binaries
Each GitHub Release contains
prebuilt full-feature binaries for:
- Linux x86-64
- macOS Intel and Apple Silicon
- Windows x86-64
Every archive has a matching .sha256 checksum file.
Install with Cargo
The crates.io package provides the CLI and library with the classical DSP and optional RNNoise backends:
For the embedded DeepFilterNet backend, use a prebuilt GitHub binary or build
this repository with its primary Cargo.toml.
Publishing a release
- Set the same version in
Cargo.tomlandCargo.crates-io.toml, then updateCargo.lock. - Commit and push the version change.
- Create and push a matching tag:
The GitHub Release workflow validates that the tag matches Cargo.toml, runs
the full test suite, builds all supported platforms, attaches archives and
checksums, signs desktop updater artifacts, and publishes generated release
notes. Installed desktop apps check the signed latest.json feed on startup;
updates are only installed after user confirmation. The updater private key is
kept in the TAURI_SIGNING_PRIVATE_KEY repository secret. A failed build leaves
the release as a draft so it cannot expose an incomplete asset set.
CLI highlights
Realtime audio
Build with the optional system-audio integration, list devices, then route a microphone through a denoising backend to an output or virtual-audio device:
Realtime processing runs outside the device callbacks and uses bounded queues,
so an overloaded backend drops stale capture chunks instead of blocking the
audio thread. --chunk-ms controls the latency/throughput trade-off and defaults
to 100 ms. Input and output devices must currently share a default sample rate.
Batch processing
Process a directory tree concurrently while preserving its relative layout:
Batch mode continues after per-file failures and reports a final success/failure
summary. Existing outputs remain protected unless --force is supplied. Omit
--output-format to retain each input file's format.
Automatic backend selection
Use --backend auto when the build contains multiple denoisers. Short and
quality-prioritized files use DeepFilterNet when available; long files use
RNNoise to bound processing cost. Realtime sessions prefer RNNoise. The
classical backend is the dependency-free fallback, and the selected backend is
reported before processing.
Adaptive noise profiling
--adaptive-noise detects spectrally noise-like, low-speech-probability regions
throughout a recording and slowly refreshes the classical estimator's anchored
noise profile. This handles changing fans, air conditioning, and room tone
without assuming that the recording begins with silence. Tonal frames are
rejected to reduce the risk of learning sustained notes as noise.
Voice activity detection
--vad detects speech with 20 ms energy frames, hangover, context padding, and
region merging. Long silent spans bypass expensive backend inference and are
strongly attenuated; enhanced speech retains a small dry-signal blend to protect
consonants and attacks. Output channel count and duration remain unchanged.
Loudness delivery
Normalize denoised output to an EBU R128 integrated-loudness target while respecting an oversampled true-peak ceiling:
The applied gain is reduced when necessary to satisfy the peak ceiling, so peak safety takes precedence over reaching the requested LUFS exactly.
Content modes
--mode speech, --mode music, and --mode ambient coordinate related DSP
controls instead of changing only one strength value. Speech mode enables VAD
and adaptive profiling; music mode prioritizes transients, stereo content, and
low suppression; ambient mode preserves environmental texture while tracking
slowly changing noise. Explicit options such as --strength still override the
mode defaults.
Optional FDK-AAC encoder
Pure-Rust oxideav-aac remains the default. Source builders can opt into the
Fraunhofer encoder and select it per invocation:
The FDK feature uses the third-party Rust port and is intentionally excluded
from full and official release binaries. Fraunhofer's codec source has its own
license and MPEG-AAC patent language; downstream distributors are responsible
for reviewing both. Enabling it raises the minimum Rust version to 1.87.
Raw ADTS AAC
.aac files are decoded and encoded directly as ADTS streams without an MP4
container or an ffmpeg conversion step. M4A and raw AAC share
--m4a-bitrate; raw ADTS output currently uses the default oxideav encoder.
Metadata preservation
File processing merges all readable input tags (for example ID3v2/ID3v1 and APE tags) and remaps the complete set of recognized fields—title, artist, album, track/disc numbers, dates, ReplayGain, lyrics, comments, and artwork—to the destination container's tag type. Cover art bytes, MIME type, picture type, and description are retained by formats that support embedded pictures.
For FLAC and Ogg outputs, arbitrary Vorbis Comment fields are copied verbatim,
including the standard CHAPTER001/CHAPTER001NAME chapter-comment convention.
When the source and destination use the same native container, format-specific
ID3v2 frames (including CHAP/CTOC) and MP4 atoms are retained as well. A
conversion to a different tag family keeps fields with a defined destination
mapping; container-specific fields without one cannot be represented there.
Use --no-metadata for a clean output.
Quality comparison
|
Quality metrics require sample-aligned PCM. Every input must have a non-zero matching sample rate, the same channel count and frame count, and equal-length channels within each file. Denoize rejects truncated or ragged inputs instead of silently scoring only their common prefix.
The report shows noisy and enhanced SI-SDR, SI-SNR, SNR, segmental SNR, stereo
side SDR, inter-channel correlation error, STOI, PESQ, ViSQOL, and improvement
deltas. It also screens for musical noise, pumping, transient loss, and stereo
phase distortion. These artifact scores are deterministic
dependency-free indicators in [0, 1] (lower is better), not perceptual
listening-test replacements; phase distortion is reported only for stereo
inputs.
When a dB metric is undefined for a silent or otherwise degenerate reference,
the report uses a finite -120 dB floor so JSON output remains valid and
machine-readable.
STOI is calculated natively for sufficiently long reference/test pairs and is
reported in [0, 1] (higher is better). ViSQOL MOS-LQO is available in the
pure-Rust build when the optional feature is enabled:
|
ViSQOL is a full-reference MOS estimate in [1, 5]. PESQ is intentionally
left as null: the ITU-T P.862 reference implementation and conformance
material require a separately licensed external adapter and are not bundled
with denoize. Inputs that are too short or a disabled optional implementation
are represented as null rather than preventing the rest of the report.
Configuration file
Reusable defaults can be stored in TOML and loaded with --config. Explicit
command-line options override the file.
= "auto"
= "hifi"
= "speech"
= 0.45
= true
= true
= -16.0
= -1.0
# deterministic = true # serialize processing for reproducible output
# seed = 12345 # optional SGMSE sampler seed (implies deterministic)
# stream_frames = 8192
# max_memory_mb = 1024
Use --deterministic when an audio result must be reproducible across runs.
The mode serializes channel/model and batch scheduling and uses a stable
stochastic-backend seed. --seed N selects an explicit SGMSE+ seed and implies
the mode. Diagnostic elapsed times and progress messages are intentionally not
part of the reproducibility guarantee.
Batch progress and recovery
Batch runs show completed files, elapsed time, and ETA. --resume records
successful outputs in .denoize-state under the output directory and skips
them on the next run. Ctrl+C stops scheduling new files; each output is first
written to a temporary file so an interrupted encode cannot replace a valid
destination. Use --no-progress for quiet operation or --json for NDJSON
progress and summary records.
-b, --backend <NAME> classical|rnnoise|deepfilter
-a, --algorithm <NAME> omlsa|logmmse|mmse|wiener|specsub|specsub-nl|specsub-geo
--window <NAME> hann|hamming|sine|blackman|kaiser|flattop|dpss
--kaiser-beta <B> Kaiser β (default 8.0)
--dpss-nw <NW> DPSS bandwidth (default 3.0)
--multiband Multiband spectral subtraction
--perceptual Bark perceptual gain weighting
--postfilter Musical-noise suppression post-filter
-p hifi Flagship preset (Kaiser + perceptual + postfilter)
--quality ultra Maximum fidelity settings
--onnx-model <PATH> Waveform ONNX model used by the onnx backend
--onnx-rate <HZ> Model sample rate (default: 16000)
Library API
use ;
let cfg = HiFi.config;
denoise_file_with_backend?;
// With DeepFilterNet (GitHub/source build with --features full)
denoise_file_with_backend?;
For embedders that use denoise_file_with_backend_config, set
BackendOptions { deterministic: true, ..Default::default() } to serialize
model/channel work. Set seed: Some(value) to reproduce SGMSE+ sampling with
an explicit seed.
Roadmap status
| Priority | Technology | Status |
|---|---|---|
| 1 | DeepFilterNet v3 | ✅ --features deepfilter |
| 2 | RNNoise | ✅ --features rnnoise |
| 3 | Kaiser/Flat-top/DPSS windows | ✅ |
| 4 | Multiband / nonlinear SpecSub | ✅ |
| 5 | Perceptual weighting + musical-noise PF | ✅ |
| 6 | Pure-Rust external ONNX inference foundation | 🟨 waveform contract implemented |
| 7 | BSRNN / MP-SENet / MossFormer2 adapters | ✅ implemented and quality-gated |
| 8 | SGMSE+ | ✅ 30-step PC sampler + score-model adapter |
See ROADMAP.md for the implementation audit and the acceptance criteria and numerical evidence for each named model.
License
The Rust project is MIT licensed. See THIRD_PARTY.md for the Apache-2.0 BSRNN conversion code and CC-BY-4.0 model attribution.