2.2 KiB
mel-scale — hertz↔mel mapping and triangular filterbank
Purpose
The mel-scale module provides the perceptual frequency warp used by MFCC and any caller that wants a psychoacoustically motivated reduction of an FFT magnitude spectrum. It exposes the Slaney/HTK closed-form hzToMel and its inverse melToHz, plus a builder that produces a triangular filterbank for a given (frameSize, sampleRate, melBands, minHz, maxHz) tuple.
Each filterbank is cached so repeated frames pay zero filter-construction cost; applying a filterbank to a magnitude spectrum is then a single dense matrix-vector multiply.
Features
- Closed-form hertz↔mel mapping that round-trips to machine precision.
- Triangular filterbank with
melBandsbands evenly spaced on the mel scale. - Per-spec caching keyed by
(frameSize, sampleRate, melBands, minHz, maxHz). - Boundary validation that
melBandsis a positive integer.
Usage: Basic
import {
applyMelFilterbank,
buildMelFilterbank,
} from "@suaveplan/audio-analysis-spectrum/algorithms/mel-scale";
const fb = buildMelFilterbank({
frameSize: 2048,
sampleRate: 48_000,
melBands: 40,
minHz: 0,
maxHz: 24_000,
});
const mel = applyMelFilterbank(spectrum, fb);
Usage: Advanced
import {
clearMelFilterbankCache,
hzToMel,
melToHz,
} from "@suaveplan/audio-analysis-spectrum/algorithms/mel-scale";
const m = hzToMel(1000);
const back = melToHz(m); // ≈ 1000 within 1e-3
clearMelFilterbankCache(); // before a benchmark sweep
API Reference
hzToMel(hz): number/melToHz(mel): number— Slaney/HTK closed forms.buildMelFilterbank(spec): MelFilterbank— cached triangular filterbank.applyMelFilterbank(spectrum, bank): Float32Array— dense mel-band vector.clearMelFilterbankCache(): void— drop every cached filterbank.
Implementation Notes
The builder allocates melBands + 2 mel-spaced points so each band has both a lower and an upper neighbour centre. Bin frequencies are computed once as (i * sampleRate) / frameSize to avoid a per-band recomputation. Each band's weights peak at 1 and taper linearly to 0 at the neighbour centres; no per-band energy normalisation is applied because the downstream MFCC log+DCT step is insensitive to global scaling.