sidespread
v0.5.0
Published
Sidespread DSP audio repair for Web and Node.js, powered by WebAssembly
Maintainers
Readme
sidespread
The sidespread npm package runs Sidespread's non-neural audio repair pipeline in WebAssembly. It
supports browsers and Node.js through one package and one API. UniverSR/ONNX neural processing is
intentionally not included in the WASM build.
Install
npm install sidespreadNode.js
import { init, process } from "sidespread";
await init();
// Interleaved stereo Float32Array: L, R, L, R, ...
const result = process(interleavedAudio, 48_000, {
dspStrength: 2,
bandwidthExtension: true,
}, (progress) => {
console.log(progress.stage, Math.round(progress.progress * 100));
});
console.log(result.report);
const repairedAudio = result.audio;Browser
Bundlers automatically select the browser entry. Initialize once before calling the synchronous DSP functions:
import { init, interleave, deinterleave, process } from "sidespread";
await init();
const source = await audioContext.decodeAudioData(arrayBuffer);
if (source.numberOfChannels !== 2) {
throw new Error("Sidespread requires stereo audio");
}
const input = interleave(source.getChannelData(0), source.getChannelData(1));
const { audio, report } = process(input, source.sampleRate, {}, (progress) => {
workerStatus.textContent = `${progress.stage}: ${Math.round(progress.progress * 100)}%`;
});
const { left, right } = deinterleave(audio);
const output = audioContext.createBuffer(2, left.length, source.sampleRate);
output.copyToChannel(left, 0);
output.copyToChannel(right, 1);Run large files in a Web Worker so synchronous DSP does not block the page's main thread. Input
must be stereo, 44.1 or 48 kHz, and normalized as finite f32 samples. The result always contains an
interleaved Float32Array; inspect report.processed to see whether any stage was applied.
Long missing-band, bandwidth, and artifact operations use bounded 8-second chunks with 250 ms of surrounding context. This keeps internal STFT memory bounded instead of scaling it across the full track. The input and final output arrays still need to fit in memory.
The optional fourth onProgress argument receives real pipeline events with a stage and overall
progress from 0 to 1. Stages are prepare, analyze, missingBand, bandwidth, artifacts,
finalize, and complete. The callback runs synchronously on the same thread as process().
Analyze Only
import { analyze, init } from "sidespread";
await init();
const report = analyze(interleavedAudio, 44_100, {
scanStartHz: 5_000,
bandwidthExtension: true,
});
if (report.needsProcessing) {
console.log(report.missingBand, report.bandwidth);
}process includes missing-band DSP repair, shared brick-wall bandwidth extension, harmonic
debleed, high-frequency smearing repair, phase stabilization, fidelity gates, and headroom control.
Use the generated TypeScript declarations for the complete options and report schema.
Build From Source
The build requires Rust with rustup, wasm32-unknown-unknown, and wasm-pack:
cd npm
npm run build
npm testApache-2.0
