Efficient real-valued FFT for 2n-size inputs. Split-radix algorithm with precomputed twiddle factors and typed-array buffers. Zero dependencies.
import rfft from 'fourier-transform'
// magnitude spectrum (N/2 bins)
const spectrum = rfft(waveform)import { fft } from 'fourier-transform'
// complex DFT output (N/2+1 bins, unnormalized)
const [re, im] = fft(waveform)Returns magnitude spectrum as Float64Array of length N/2.
input—Float32Array,Float64Array, or plainArray. Length must be power of 2 (>= 2).output— optionalFloat64Array(N/2)to write into.- Returns internal buffer if no output provided (overwritten on next call with same N).
Normalization: a unit-amplitude cosine at frequency bin k produces spectrum[k] = 1.0.
Returns complex DFT as [re, im], each Float64Array of length N/2+1 (DC through Nyquist).
output— optional[Float64Array(N/2+1), Float64Array(N/2+1)].- Unnormalized:
X[k] = sum( x[n] * e^(-j*2*pi*k*n/N) ). - DC and Nyquist bins always have
im = 0(real input).
Both functions return internal cached buffers by default. The next call with the same N overwrites the previous result. Pass an output buffer to keep results across calls:
const out = new Float64Array(N / 2)
rfft(signal, out) // safe to keepN=4096 real-valued FFT, complex output, 20k iterations (lower is better):
fft.js (indutny) 16.5µs ×1.0 — radix-4, interleaved output
fourier-transform 17.8µs ×1.1 — split-radix, separate re/im
ooura 23.6µs ×1.4 — Ooura C port
ml-fft 37.0µs ×2.2
dsp.js 48.1µs ×2.9 — our split-radix ancestor
kissfft-wasm 49.4µs ×3.0 — WASM KissFFT
ndarray-fft 63.1µs ×3.8
als-fft 2311.4µs ×140
fft-js 2329.2µs ×141 — naive recursive
Raw transform speed is identical to fft.js. The gap is the cost of returning separate re/im arrays vs interleaved output.
npm run benchmark to reproduce.
Based on the split-radix real FFT from dsp.js by @corbanbrook, itself derived from RealFFT.
MIT