mel_spec

Library Listed

Mel spectrograms aligned to the results from the whisper.cpp, pytorch and librosa reference implementations and suited to streaming audio.

Checked · Sources

Downloads
26,437
Dependents
6
Stars
91
Forks
13
Contributors
7
Commits
145
Latest release
0.5.0 ·

About

From the project README ·

Rust mel spectrogram, filterbank, and VAD components for ASR systems.

Release note: 0.5.0 makes CPU feature extraction faster. The CPU paths use a real-input FFT, and the batch paths project eight frames at a time. Results match 0.4.1 within FFT rounding. Details are in CHANGELOG.md.

Speedup (11 s JFK sample, one Apple M1 core)
Batch log-mel1.9-2.0x
Whisper mel1.7-2.0x
Kaldi fbank1.5x
VAD3.7x
Read the full README

Main Features

FeatureAPIUse
Batch log-mel frontendBatchLogMelSpectrogramWhole-utterance log-mel features with centered framing, pre-emphasis, padding, and per-feature normalization. The Parakeet/NeMo frontend in asr-api uses it.
Whisper-compatible melSpectrogram, MelSpectrogramStreaming and batch log-mel spectrograms that match whisper.cpp, PyTorch, and librosa.
Kaldi-compatible fbankFbankKaldi-style filterbank features with the Povey window, the Kaldi mel scale, and CMN.
Mel filterbanksmel, SparseMelFilterbankSlaney or HTK filterbank matrices, and the sparse form that the CPU paths execute.
Streaming inputRingBufferBounded sample buffer that gives one mel frame for each hop. The rtrb feature uses an rtrb ring buffer.
Interleaved PCMcompute_interleaved, downmix_interleavedDownmix of stereo or multichannel PCM before batch feature extraction.
Model-free VADVoiceActivityDetector, vad_boundariesSpeech decisions and timestamps from the edge structure of mel frames.
TGA mel imagestga_8bit, save_tga_8bit, load_tga_8bitQuantized 8-bit mel spectrograms in TGA files.
WASM workerSpeechToMel (wasm feature)Mel frames, quantization, and VAD in a browser worker. Hush uses it for local Whisper transcription.
GPU backendsWgpuMelSpectrogram, CudaMelSpectrogramExperimental batched mel generation with wgpu (Metal, Vulkan, DX12) or cuda (NVIDIA).

Quick Start

use mel_spec::prelude::*;

let samples = vec![0.0_f32; 16_000];
let mel_frames = Spectrogram::compute_mel_spectrogram_cpu(
    &samples,
    400,
    160,
    80,
    16_000.0,
);

println!("frames={}", mel_frames.len());

For whole utterances, BatchLogMelSpectrogram gives feature-major output. Keep the scratch buffers to reuse them across calls:

use mel_spec::prelude::*;

let frontend = BatchLogMelSpectrogram::new(BatchLogMelConfig::default()).unwrap();
let mut scratch = frontend.scratch();
let samples = vec![0.0_f32; 16_000];
let features = frontend.compute_with_scratch(&samples, &mut scratch).unwrap();

assert_eq!(features.shape(), &[80, 101]);

Use BatchLogMelSpectrogram::compute_interleaved for interleaved audio. The method averages all input channels before feature extraction.

The focused API examples are kept in the example READMEs so the top-level README stays readable:

ExampleDescription
browserStream microphone or WAV audio to a WASM mel worker.
mel_tgaConvert raw audio to TGA mel spectrogram images.
tga_whisperTranscribe precomputed TGA mel spectrograms with whisper.cpp.
stream_whisperStream ffmpeg audio through mel, VAD, and Whisper.
vad_ten_evalEvaluate mel-spec VAD against the vendored TEN-VAD testset.

Voice Activity Detection

mel-spec includes a lightweight, model-free VAD. It does not load a neural VAD runtime. It looks for speech-like Sobel edge structure in mel spectrogram frames and can attach STFT-derived timestamps to each decision.

Current balanced default on the checked-in TEN-VAD testset:

SystemSettingMacro precisionMacro recallMacro F1Macro FPRRTFx
mel-specbalanced default0.87510.87850.85660.3946819.6
mel-spechigh-F1 sweep result0.81650.96350.87690.6459828.9
Silerotuned threshold 0.130.88970.93880.90880.3602110.3
Silerodefault threshold 0.500.93790.86300.88260.1778110.6

The balanced default is not trying to beat learned VADs at strict endpointing. It is a fast built-in option that reuses ASR mel features and avoids another model dependency. Tuned Silero is still more accurate overall. TEN-VAD is the source of the labels and upstream reports stronger precision/recall than Silero and WebRTC on the same testset.

Detailed method, provenance, commands, speed notes, and per-file results are in doc/vad/README.md.

TGA Spectrograms

TGA spectrograms are useful when you want a simple interchange format for mel features. They can be inspected as images, spliced, stored, and passed to the Whisper examples without keeping the original audio around.

This path is live in Hush as local browser ASR. The browser uses the Whisper-compatible log-mel output from mel-spec. It stores captured speech as compact 8-bit TGA images. It decodes the images to an 80-mel Float32Array and passes the tensor to whisper_set_mel in a custom whisper.cpp WASM binding. The active Hush deployment verifies that local WASM Whisper can transcribe from the mel tensor without posting microphone audio to a server. This uses the proposed direct-mel entry point for whisper.cpp, not the stock browser example that feeds PCM audio into whisper.wasm.

image "the quest for peace."

Mel spectrograms are also robust under heavy quantization. Whisper does not need high-precision PCM after projection into mel space. Eight-bit TGA images preserve the information that the model sees. Coarse mel-value rounding can also retain useful transcription quality.

Original: [0.158, 0.266, 0.076, 0.196, 0.167, ...]
Rounded:  [0.2,   0.3,   0.1,   0.2,   0.2,   ...]

original quantized mel spectrogram coarsely rounded quantized mel spectrogram (top: original mel values, bottom: values rounded to 1.0e-1 before image quantization)

Performance

mel-spec 0.5.0 on the 11-second JFK sample, one Apple M1 core, release build:

PathTimeRealtime factor
BatchLogMelSpectrogram, Parakeet configuration1.13 ms9,700x
BatchLogMelSpectrogram, default configuration0.95 ms11,600x
Spectrogram::compute_mel_spectrogram_cpu (Whisper)1.97 ms5,600x
Spectrogram::add and MelSpectrogram::add (Whisper, streaming)2.53 ms4,300x
RingBuffer2.34 ms4,700x
Fbank::compute2.13 ms5,200x
VoiceActivityDetector::add_activity0.23 ms47,000x

The Parakeet configuration has 128 mels, pre-emphasis 0.97, and per-feature normalization. The time increases linearly with the audio length: 66 seconds of audio take 6.8 ms in the Parakeet configuration.

mel() and the Kaldi filterbank builder produce dense filterbank matrices for reference, fixture comparison, and interchange with other toolchains. The CPU paths execute a sparse form of the same matrices, with one contiguous band of weights for each mel row. Tests compare the sparse projection with the dense matrices.

Parakeet/NeMo Frontend Comparison

asr-api uses BatchLogMelSpectrogram for its Parakeet/TDT frontend. The parakeet_featurizer_bench harness in asr-torch compares this frontend with a CPU TorchScript trace of the NeMo Parakeet featurizer (featurizer_cpu.pt). The comparison used the JFK sample on an M1 Mac and mel-spec 0.4.0.

FeaturizerShapeMeanp50p95RTFx
Rust Parakeet frontend using mel-spec 0.4.0128x11012.341ms2.334ms2.406ms4699.62
TorchScript CPU trace128x11012.244ms2.206ms2.813ms4902.22

Feature comparison across the full tensor:

MetricValue
MAE0.001183
RMSE0.023699
Max absolute error3.965733
Correlation0.999719

The mel-spec benchmark gives 2.26 ms for 0.4.1 and 1.13 ms for 0.5.0 in this configuration. On the first three seconds of the JFK sample, the 0.5.0 features differ from 0.4.1 by a mean absolute difference of 1.2e-6.

GPU Backends

The CPU path is the default. Experimental native GPU backends are available behind feature flags:

FeatureBackend
cudaNVIDIA-only cuFFT plus CUDA mel projection.
wgpuNative Rust GPU backend for Metal, Vulkan, and DX12 systems.

Build Checks

The top-level library tests do not automatically build every standalone example crate. Use these commands when changing examples:

cargo test --release
MEL_SPEC_FUZZ_SCALE=50 cargo test --release fuzz_
cargo build --release --manifest-path examples/mel_tga/Cargo.toml
cargo build --release --manifest-path examples/stream_whisper/Cargo.toml
cargo build --release --manifest-path examples/tga_whisper/Cargo.toml
cargo run --release --manifest-path examples/vad_ten_eval/Cargo.toml
(cd examples/browser && npm ci && npm test)

MEL_SPEC_FUZZ_SCALE multiplies the number of cases in the seeded random tests. The Whisper examples compile against the wavey-ai/whisper-rs fork and require a GGML Whisper model to run inference.

Hush Demo

The Hush live browser demo is active at:

https://wavey.ai/code/hush/?v=20261003-36

The source remains at wavey-ai/hush. With the current tuned settings it works as a live browser VAD, spectrogram debugging view, and local Whisper WASM transcription demo. It exposes mel structure, Sobel edges, ridge tracks, candidate speech regions, and the local transcript in real time. The VAD itself should still be treated as experimental rather than a drop-in replacement for a learned VAD. One strong use case is as a browser-side feature/debugging front end or cheap prefilter before a stronger VAD/ASR model.

image

Runs on
CUDA, WebGPU
What shows it
  • CUDA: mel_spec feature cuda
  • WebGPU: mel_spec feature wgpu (dependency wgpu)
Native code
Optional
  • Binds native code: ort-sys (feature ort-tensor)
  • Build uses a native toolchain: cc
Python bindings
No Python binding crate found
License
MIT

Compare with similar projects

Order: strongest tier first, then most downloads, then name, with unmeasured values last. A library counts downloads over 30 days. An app counts binary downloads per release. An app with none counts its crate downloads over 30 days. ML Rust runs this catalogue, so its closest project always gets a row.

mel_spec beside the projects that share a topic with it
ProjectDownloadsDependentsStarsLatest releaseRuns on (GPU)Native codeLicense
mel_spec This page Listed

Mel spectrograms aligned to the results from the whisper.cpp, pytorch and librosa reference implementations and suited to streaming audio.

26,437 downloads over 30 days 6 91 0.5.0 CUDA, WebGPU Binds native code: ort-sys (feature ort-tensor). Build uses a native toolchain: cc MIT
whisper-rs Featured

Rust bindings for whisper.cpp

466,717 downloads over 30 days 98 Not measured 0.16.0 CUDA, Metal, Vulkan Binds native code: piper, piper1-rs-sys, whisper, whisper-rs-sys. Build uses a native toolchain: bindgen, cmake Unlicense
nnnoiseless Featured

Audio denoising, derived from Xiph's RNNoise library

172,829 downloads over 30 days 27 370 0.5.2 GPU support unknown Binds native code: hdf5-sys (feature train) BSD-3-Clause
scribble Listed

High-level Rust API for audio transcription using Whisper

457 downloads over 30 days 0 105 0.5.4 CUDA, Metal, Vulkan Binds native code: whisper-rs-sys MIT
whisrs App Listed

Voice for the Linux desktop: dictation, read-aloud (TTS), and voice-driven LLM commands, with Groq, OpenAI, Deepgram, and local Whisper backends

61 binary downloads per release Not applicable 149 0.2.0 CUDA, Vulkan Binds native code: alsa-sys, mac-notification-sys, wayland-sys (feature overlay), whisper-rs-sys (feature local-whisper) MIT
voxr New

Audio and speech on boostr: compressed-audio decode, resampling, DSP and grapheme to phoneme, with speech synthesis (Kokoro, VITS), voice cloning (VoxCPM2), transcription with word timings (Whisper), voice activity (Silero) and audio-text scoring (CLAP), on CPU or CUDA.

642 downloads over 30 days 2 2 0.9.1 CUDA No native code found Apache-2.0
Why ListedNo archive, New or Featured rule places it, so it is Listed.

What it lacks for Featured

  • It has 3 active dependents and 2 new dependents in 365 days. Featured needs 11 active dependents or 9 new dependents in 365 days. The repository route reads 91 stars, 13 forks and 7 contributors. It needs 4,539 stars, 434 forks and 79 contributors together.

What else the check found

  • The last activity is on 2 Oct 2026, 38 days ago. The rules expect an update within 365 days. Dormancy rule

Exact rules: Listed, Featured library. The check on applied thresholds version 9.

Every rule outcome, as the check records it
  • expected-interval: version 0.5.0 base 140, raised to the 365-day floor: E = 365 days
  • dormancy: last activity 2026-10-02, 38 days ago, E = 365: active
  • featured: not featured: active_users 3 < 11 and new_adopters 2 < 9 and repository route stars 91 (needs 4539), forks 13 (needs 434), contributors 7 (needs 79)
  • listed: listed: no archive, new or featured rule applies
Crates2 crates

Measurements and sources

Each signal row shows the raw value, its source and the fetch date. The Sources list gathers every distinct source on this page. Movement needs more history.

Sources6 sources
Adoption3 active dependents, 2 new dependents in 365 days1 not measured
Adoption measurements
SignalValueSourceFetchedCounts
Active dependents3crates.io database dumpYes
New dependents (365 days)2crates.io database dumpYes
Peak active dependents4crates.io database dumpYes
Active dependents as a share of the peak1crates.io database dumpYes
Binary downloads per releaseNot measuredYes
MaintenanceLatest human commit: 38 days ago3 not measured
Maintenance measurements
SignalValueSourceFetchedCounts
Latest human commit2026-10-02GitHub repositoryYes
Latest release2026-10-02crates.io database dumpYes
First release2023-07-22crates.io database dumpYes
Latest version0.5.0crates.io database dumpYes
Days the oldest outside issue waits for a reply0GitHub repositoryYes
Maintainer replies over 365 days0GitHub repositoryYes
Repository archivedfalseGitHub repositoryYes
Repository gonefalseGitHub repositoryYes
Release commit or manifest in the repotruecrates.io packageYes
Published docstruecrates.io database dumpYes
Latest release fails cargo checkNot measuredYes
Build check dateNot measuredYes
Build check toolchainNot measuredYes
SecurityUnpatched vulnerabilities: none
Security measurements
SignalValueSourceFetchedCounts
Unpatched vulnerabilities past the grace windownoneRustSec advisory databaseYes
RustSec unmaintained advisorynoneRustSec advisory databaseYes
Deprecation noticenonecrates.io database dumpYes
Deprecated requirementnonecrates.io database dumpYes
Distribution17 releases, 26,437 downloads over 30 days5 not measured
Distribution measurements
SignalValueSourceFetchedCounts
Releases17crates.io database dumpYes
Downloads over 30 days26437crates.io database dumpYes
Binary downloads over the last 3 releasesNot measuredYes
Homebrew installs on request over 365 daysNot measuredYes
Repology repository familiesNot measuredYes
Docker pull growth over 90 daysNot measuredYes
Docker pulls at the growth baselineNot measuredYes
Every version a prereleasefalsecrates.io database dumpYes
Every version 0.0.xfalsecrates.io database dumpYes
Every version yankedfalsecrates.io database dumpYes
Crate deleted from crates.iofalsecrates.io database dumpYes
Repository91 stars, 13 forks, 7 contributors, 145 commits. Stars alone never qualify a project.
Repository measurements
SignalValueSourceFetchedCounts
GitHub stars91GitHub repositoryYes — one part of the repository route
GitHub forks13GitHub repositoryYes — one part of the repository route
Contributors with a GitHub account7GitHub contributorsYes — one part of the repository route
Commits on the default branch145GitHub repositoryNo
Repository's main crate left out of the entrynonecrates.io database dumpYes
Facts that never count
Facts that never count measurements
SignalValueSourceFetchedCounts
LicenseMITcrates.io database dumpNo
Runs on, from listed crates and their direct dependenciesCUDA, WebGPUcrates.io database dumpNo
What shows each backendCUDA: mel_spec feature cuda; WebGPU: mel_spec feature wgpu (dependency wgpu)crates.io database dumpNo
Native code, from listed crates and their dependenciesBinds native code: ort-sys (feature ort-tensor). Build uses a native toolchain: cccrates.io database dumpNo
Python bindings, from direct dependencies of listed cratesNo Python binding crate foundcrates.io database dumpNo
Crates that depend on a listed crate directly6crates.io database dumpNo

Corrections and review history

Report a correction

No correction applies to this entry.

Judgments

A judgment enters only through an approved issue and a merged pull request.

No judgment applies to this entry.