Keep the speech. Drop the rest.

AeroSieve cuts raw recordings into 3–30 second clips, measures each one for noise, clipping, tones and silence, and writes the keepers as WebDataset shards. Every clip it throws away comes with a reason.

Try it in your browser

Caught 24,385 of 24,409 damaged clips across six languages · MIT · CLI, Python, Rust

  • No GPU, no model required
  • Your audio never leaves the browser
  • A reason for every rejection

Passed through

    Caught, with a reason

      Drop in a recording. See what your model would learn from.

      This is the same Rust code as the command-line tool, compiled to WebAssembly. Nothing is uploaded.

      Loading the WebAssembly build…

      StartLengthSNR dBdBFSClipFlatnessVerdictWhy

      Thresholds

      Moving a slider re-applies FilterPolicy to the stored measurements. Nothing is decoded again.

      Drag any wav, mp3, flac, ogg or mp4 onto this panel. Recordings up to 15 minutes.

      Samples are LibriSpeech utterances (CC BY 4.0) with noise, clipping and a dial tone added.

      Raw audio in. Training shards out.

      wavmp3flacoggmp4
      16 kHz mono−20 dBFS, ±3 dB

      Any container in

      Decoded, downmixed, resampled and leveled in one pass, following the first stage of Emilia-Pipe.

      0 dBfloor 1030 dB

      Noise without a reference

      WADA-SNR estimates noise from the clip alone. No clean copy needed.

      Clips of 3 to 30 seconds

      A hysteresis VAD finds speech and cuts it where people pause. Silero VAD is optional.

      shard-000000.tar manifest.jsonl stats.json {"key":"call-0412-000","shard":0,"wada_snr_db":20.4,…}

      WebDataset shards and a manifest

      Every kept clip is a wav and a json in a tar shard. aerosieve nemo-manifest adds NVIDIA NeMo's layout.

      Clipping, even after leveling

      Measured against the source's own full scale, so turning a file down can't hide it.

      Tones and hum

      Spectral flatness in the 300–3400 Hz band catches dial tones without flagging phone audio.

      max_duration_s enforced while decoding allocations bounded by file headers one run per output directory

      Safe on untrusted input

      A small compressed file can't expand without bound, and a finished run can't be overwritten.

      SieveBench

      We broke clean speech on purpose.

      Noise at six levels, clipping, tones, hum, near-silence and a phone line, injected into real recordings in six languages. Every damaged clip goes through the same code as the CLI.

      24,385 of 24,409 damaged clips caught, out of 51,352 damaged copies of 1,834 real recordings in six languages. On a laptop CPU.

      By language

      LanguageAudioUntouched audio keptOver a phone lineDefects caughtNamed the right defect

      FLEURS is read speech recorded on volunteers' own devices, so some untouched clips really are noisy: most of what Hindi, Tamil and Bengali lose is source audio already under the 10 dB floor. LibriSpeech, recorded for audiobooks, keeps every clean clip.

      How close is the noise estimate?

      Median WADA-SNR reading against the noise level actually injected. Hover a point for the spread.

      White and pink noise read within about 1.3 dB of the truth from 0 to 20 dB. Babble, other people talking, reads up to 2.7 dB cleaner than it is, because it looks like speech. Above 20 dB the curves flatten at the recordings' own noise floor.

      What it caught in AeroSieve itself

      1. Clipping hid behind loudness leveling

        A loud, clipped file was turned down 3 dB before scoring, so its flat tops sat at 0.7 and passed as clean. Clipping is now measured against the source's own full scale.

      2. Speech was cut at every word gap

        A 100 ms pause ended a clip, so natural speech broke into fragments under 3 s and was dropped: 23 of 73 clean English recordings produced nothing.

        Same 43 min of Hindi16.4 → 25.6 minof usable speech, +56%

      Speed

      940×

      faster than real time: 43 minutes of Hindi as 48 kHz FLAC, decoded, resampled, segmented, scored and sharded in 2.75 s.

      8 threads on one laptop. Files are inspected in parallel and written in order, so shards match a single-threaded run byte for byte.

      48 kHz FLAC, 8 threads
      2.75 s
      48 kHz FLAC, 1 thread
      8.1 s
      16 kHz WAV, 8 threads
      0.55 s
      Verdict latency, 1,000 live streams (p95)
      14.8 ms

      Every number in this section is reproduced by crates/aerosieve-sievebench/scripts/run_all.sh.

      Four stages. One pass.

      Cheap checks run before expensive ones, and each stage is its own crate you can use alone.

      1. Decode

        Symphonia reads the container, rubato resamples to 16 kHz, and loudness is leveled toward −20 dBFS.

        aerosieve-decode
      2. Segment

        A hysteresis state machine with Silero's defaults turns speech probability into 3–30 s clips.

        aerosieve-segment
      3. Score

        Four measurements per clip, then a FilterPolicy that names the first check a clip fails.

        aerosieve-acoustic
      4. Shard

        Kept clips go into WebDataset tar shards with a JSONL manifest and run totals.

        aerosieve-shard

      Use it from the command line, Python, Rust, or a live stream.

      $ cargo install aerosieve-cli
      $ aerosieve inspect recordings/
      recordings/call-0412.wav (33.6 s, 8000 Hz source)
          START  LENGTH   SNR dB     dBFS   CLIP  FLATNESS  VERDICT
           0.0s   23.4s     20.4    -23.7  0.000     0.149  accept
          23.4s   10.2s     18.1    -26.0  0.000     0.182  accept
      $ aerosieve curate recordings/ --out data/run-1

      What it doesn't do yet.

      The thresholds have been checked on a few hours of audio, not against human ratings. FLEURS has no noise labels, so the tables above show what the filter does, not whether each rejection is right.

      • A single sustained instrument can pass as speech.
      • One transcript per file is copied to every clip. Transcripts aren't aligned to clips.
      • Speech is found by signal level unless you build with Silero VAD.
      Read the full list

      Clean data is a choice.
      Make it on purpose.

      Source code

      MIT licensed · crates.io · docs.rs