erm: Local CLI for Automated Speech Disfluency Removal

Automated removal of speech disfluencies

erm is a local command-line interface (CLI) tool designed to automatically strip "disfluencies"—filler sounds such as um, uh, and er—from audio recordings. Unlike naive cutting approaches that result in audible clicks and jarring transitions, erm employs a multi-pass detection system and signal processing techniques to ensure the resulting audio sounds natural.

Why naive audio cutting fails

Simply transcribing audio and cutting out the timestamps associated with filler words is insufficient for three primary reasons:

  1. Transcription Gaps: Speech-to-text models like OpenAI's Whisper often automatically omit filler words from the transcript, leaving no token to target for removal.
  2. Waveform Steps: Slicing audio at arbitrary timestamps creates a "step" in the waveform, which the human ear perceives as a click.
  3. Ambient Noise Mismatch: Even with a clean splice, the background hiss (room tone) before and after a cut often differs slightly, creating a perceptible shift in the audio floor.

The erm detection pipeline

To overcome the limitations of transcription, erm uses a four-pass detection process to identify filler sounds:

1. Whisper Transcription

erm uses faster-whisper (specifically the medium.en model by default) to generate word-level timestamps. It provides specific instructions to the model to avoid cleaning up the transcript, ensuring that um, uh, and er tokens are captured and flagged.

2. Gap Filler Detection

If a pause between transcribed words exceeds 350ms, erm analyzes the audio in that gap. If voiced sound is detected where Whisper marked silence, the tool identifies it as a filler that the model deleted from the transcript.

3. Internal Word Splitting

When Whisper glues a filler to an adjacent word (e.g., "in, uhhhhh" as a single token), erm identifies unusually long tokens and splits them at brief audio dips to isolate the filler from the actual word.

4. Duration and Pitch Analysis

For words that last longer than plausibly possible for their text, erm scans the tail end for voiced sound. It uses a pitch test to distinguish between a held vowel (characteristic of a filler like uhhhhh) and a slow speaker, ensuring that only the fillers are trimmed.

Signal processing for seamless splicing

To prevent audible artifacts, erm applies several refinement steps to every cut point:

  • Quiet-Spot Sliding: Cut endpoints can slide up to 60ms to find the quietest local point, provided they do not overlap with neighboring words.
  • Zero-Crossing Snapping: Endpoints snap to the nearest moment where the waveform crosses zero, ensuring a continuous waveform and eliminating clicks.
  • Sliver Removal: Any surviving audio fragments shorter than 120ms between two cuts are merged into a single larger cut to avoid "blips."
  • Dynamic Crossfading: Using ffmpeg, erm overlaps the spliced audio. The crossfade length is scaled based on the size of the cut (between 50ms and 120ms) to avoid smearing short clips or popping long ones.

Maintaining audio consistency

Room Tone Looping

To mask the shift in background hiss across cuts, erm identifies a quiet stretch of the original recording and loops it at a low volume underneath the entire output. This creates a consistent audio floor that covers the splices.

Strategic Denoising

erm offers four denoising modes to ensure that noise reduction does not interfere with detection. The default hybrid mode runs detection on the original audio (to preserve the cues used for identification) but performs the actual cuts from a denoised copy of the audio.

Scope and Limitations

erm specifically targets sounds, not language. It removes um, uh, and er, but intentionally ignores:

  • Filler words: like, you know, and I mean are preserved because they are linguistic elements that could change the meaning of a sentence.
  • Editorial choices: Repeated words, false starts, and long thinking pauses are left intact, as removing them requires editorial judgment rather than simple noise removal.

User Workflow and Validation

The tool can be run via uvx for an immediate trial or installed via pip:

# Dry run to see what would be cut
uvx erm input.wav --dry-run

# Render the cleaned file
uvx erm input.wav

To ensure the output is correct, the validate subcommand checks if the file opens, verifies the total length reduction matches the cut list, and re-transcribes the cleaned file to confirm that fillers are gone.

Community Perspectives

While the tool solves a technical challenge, the necessity of removing disfluencies is debated. Some users find it invaluable for professional content:

I make online course content and used to lose close to a full day cutting filler out of every hour so of recording. This gets me maybe 70% of that time back.

Others argue that disfluencies serve a cognitive purpose in speech:

In speech however it [the 'um'] can serve as a focusing point to indicate the next part is important.

Additionally, some critics suggest that removing these sounds is an editorial decision that can change the meaning or cadence of a speaker, particularly for non-native English speakers.

Sources