You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Zero-dependency digital signal processing: FFT/IFFT, spectrum analysis, FIR filter design, window functions, and signal utilities — TypeScript-first npm equivalent of Python's scipy.signal, Go's gonum/dsp, Java's JTransforms.
import{fft,magnitudeSpectrum,dominantFrequency,generateSine,lowpassFilter,applyFilter}from"@billdaddy/dspkit";// Generate a 440 Hz sine wave at 44100 Hz sample rateconstsignal=generateSine(440,1.0,44100,4096);// Compute FFT and find dominant frequencyconstspectrum=fft(signal);const{ magnitude, frequencies }=magnitudeSpectrum(spectrum,44100);constfreq=dominantFrequency(magnitude,frequencies);// ≈ 440// Design a 1 kHz lowpass FIR filter and apply itconstcutoff=1000/44100;// normalized (0–0.5)consth=lowpassFilter(cutoff,128);constfiltered=applyFilter(signal,h);
Why dspkit?
Every major scientific computing ecosystem ships DSP primitives in its standard or near-standard library:
The only npm package attempting this space — dsp.js — was self-declared unmaintained as of 2014, has no TypeScript support, and receives ~38k downloads per week only because no alternative exists. dspkit is its modern, zero-dep, TypeScript-native replacement.
Install
npm install @billdaddy/dspkit
Usage
FFT / IFFT
import{fft,ifft,fftConvolve,nextPow2}from"@billdaddy/dspkit";// Real-valued signal → complex spectrum (auto zero-pads to next power of 2)constspectrum=fft([1,2,3,4,5,6,7,8]);spectrum.re;// real partsspectrum.im;// imaginary partsspectrum.length;// 8 (already a power of 2)// Non-power-of-2 inputs are zero-padded automaticallyfft([1,2,3]).length;// 4// Inverse FFT → recover original signalconstback=ifft(spectrum);back.re;// ≈ [1, 2, 3, 4, 5, 6, 7, 8]// FFT-based convolution: O(N log N) vs direct O(N*M)constresult=fftConvolve([1,2,3],[4,5,6]);// → Float64Array([4, 13, 28, 27, 18])
Spectrum analysis
import{fft,magnitude,powerSpectrum,phase,magnitudeSpectrum,dominantFrequency,rms,peak,crestFactor}from"@billdaddy/dspkit";constc=fft(signal);magnitude(c);// |X[k]| — amplitude at each binpowerSpectrum(c);// |X[k]|² — power at each binphase(c);// atan2(im, re) — phase at each bin// One-sided magnitude spectrum with physical frequency labelsconst{magnitude: mag, frequencies }=magnitudeSpectrum(c,44100);// mag[k] is amplitude at frequencies[k] HzdominantFrequency(mag,frequencies);// frequency with highest amplitude// Time-domain statisticsrms(signal);// root-mean-square energypeak(signal);// maximum absolute valuecrestFactor(signal);// peak / rms
Window functions
Reduce spectral leakage when your signal doesn't contain an integer number of cycles.
import{hannWindow,hammingWindow,blackmanWindow,bartlettWindow,nuttallWindow,blackmanHarrisWindow,flatTopWindow,rectangularWindow,applyWindow,coherentGain,getWindow}from"@billdaddy/dspkit";constN=1024;constw=hannWindow(N);// → Float64Array of length NapplyWindow(signal,w);// element-wise multiply signal × windowcoherentGain(w);// mean of window (≈ 0.5 for Hann)// Get window by namegetWindow("blackman",N);// one of: rectangular|hann|hamming|blackman|bartlett|nuttall|blackman-harris|flat-top
Window
Sidelobe level
Main lobe width
Use case
Rectangular
-13 dB
Narrowest
Never leak matters
Hann
-31 dB
Moderate
General purpose
Hamming
-41 dB
Moderate
General purpose
Blackman
-57 dB
Wide
Low sidelobes
Nuttall
-93 dB
Wide
Very low sidelobes
Blackman-Harris
-92 dB
Wide
Very low sidelobes
Flat-Top
-44 dB
Widest
Amplitude accuracy
FIR filter design (windowed-sinc)
All cutoff frequencies are normalized: cutoff = f_Hz / f_sample. Valid range: (0, 0.5) where 0.5 = Nyquist.
import{lowpassFilter,highpassFilter,bandpassFilter,bandstopFilter,applyFilter}from"@billdaddy/dspkit";constsampleRate=44100;// Lowpass: pass < 2 kHz, attenuate > 2 kHzconstlp=lowpassFilter(2000/sampleRate,128);// order 128 → 129 coefficients// Highpass: pass > 5 kHz, attenuate < 5 kHzconsthp=highpassFilter(5000/sampleRate,128);// Bandpass: pass 300–3400 Hz (telephone band)constbp=bandpassFilter(300/sampleRate,3400/sampleRate,128);// Bandstop (notch): suppress 50 Hz power-line humconstbs=bandstopFilter(45/sampleRate,55/sampleRate,128);// Apply any FIR filter to a signal (causal, same output length as input)constfiltered=applyFilter(signal,lp);// Note: group delay = order/2 samples (filter is linear-phase)
import{generateSine,generateCosine,generateSquare,generateNoise,linspace}from"@billdaddy/dspkit";constsr=44100,n=4096;generateSine(440,1.0,sr,n);// A4 at full amplitudegenerateCosine(440,0.5,sr,n);// half-amplitude cosinegenerateSquare(100,1.0,sr,n,10);// square wave (10 harmonics)generateNoise(0.1,n);// white noise at 10% amplitudelinspace(0,1,11);// [0, 0.1, 0.2, ..., 1.0]
Signal utilities
import{zeroPad,mean,removeDC,normalize,toDb,fromDb}from"@billdaddy/dspkit";zeroPad(signal,512);// extend with zeros to length 512mean(signal);// arithmetic meanremoveDC(signal);// subtract mean (remove DC offset)normalize(signal);// scale so peak absolute value = 1toDb(0.5);// ≈ -6 dBfromDb(-6);// ≈ 0.5