CallCleaner

Lightweight bioacoustic denoising from an audio foundation model.

CallCleaner removes background noise (wind, rain, vehicles, other animals) from recordings of animal vocalizations. It is a 19M-parameter waveform-to-waveform model that needs no detector, text prompt or GPU, and runs about 90脳 faster than real time on a laptop CPU.

Project page 路 Paper (arXiv, link coming) 路 Code (GitHub)

How it was made

The source-separation foundation model SAM-Audio (facebook/sam-audio-small), prompted with "animal sound" and with time spans from a simple animal voice-activity detector, removes more noise from animal calls than dedicated bioacoustic denoisers, but it is slow and inherits detector errors. CallCleaner distills it into a small model:

  • Architecture: the Demucs denoiser from Biodenoising (biodenoising16k_dns48, 16 kHz, mono), initialized from Biodenoising's weights.
  • Teacher: SAM-Audio with VAD-span prompts. Its target stream is the pseudo-label; its residual stream is a noise estimate. Half of each batch is remixed (another segment's residual added to a pseudo-label), as in bootstrapped remixing.
  • Data: 4 s segments (1.8 h) from the public corpora Biodenoising was trained on (DCASE few-shot bioacoustics, Orchive and five bird corpora), none shared with its benchmark.
  • Training: 2,000 steps.

On Biodenoising's benchmark (47 clips 脳 4 SNRs), CallCleaner leaves 11 dB less noise around the call than Biodenoising, the leading neural bioacoustic denoiser with public weights, and among fast, CPU-capable systems it pushes the Pareto frontier of noise removal vs. call fidelity. See the paper for full results.

Usage

pip install biodenoising safetensors huggingface_hub librosa soundfile
import librosa, soundfile as sf, torch
from biodenoising.denoiser.pretrained import biodenoising16k_dns48
from huggingface_hub import hf_hub_download
from safetensors.torch import load_file

model = biodenoising16k_dns48(pretrained=False)
model.load_state_dict(load_file(hf_hub_download("malper/CallCleaner", "model.safetensors")))
model.eval()

y, _ = librosa.load("noisy.wav", sr=16000, mono=True)       # the model works at 16 kHz, mono
with torch.no_grad():
    clean = model(torch.tensor(y)[None, None])[0, 0, : len(y)].numpy()
sf.write("clean.wav", clean, 16000)

For long recordings, process overlapping chunks (e.g. 60 s with a 1 s cross-fade); the command-line script in the code repository does this, and handles folders and other sample rates.

Limitations

  • Output is 16 kHz: content above 8 kHz (e.g. many bat and some bird and insect calls) is not restored.
  • Trained to keep one caller's vocalizations; overlapping calls from other animals may be treated as noise.
  • Distilled from a teacher that can miss quiet calls or keep loud non-target sounds; it inherits some of these errors. Listen to outputs before using them for analysis.

License

The weights are a derivative of SAM-Audio and are released under the SAM License (see LICENSE); by using or redistributing them you agree to its terms. The Biodenoising architecture and initialization are MIT-licensed.

Citation

@article{xie2026callcleaner,
  title  = {CallCleaner: Lightweight Bioacoustic Denoising from an Audio Foundation Model},
  author = {Xie, Michael and Begu{\v{s}}, Ga{\v{s}}per and Alper, Morris},
  year   = {2026}
}
Downloads last month
-
Safetensors
Model size
18.9M params
Tensor type
F32
路
Inference Providers NEW
This model isn't deployed by any Inference Provider. 馃檵 Ask for provider support