sonic-wasm
v0.0.1
Published
WebAssembly bindings for libsonic audio time-stretching
Downloads
115
Maintainers
Readme
sonic-wasm
WebAssembly bindings for libsonic - a fast, high-quality audio time-stretching and pitch-shifting library.
Features
- Time-stretch audio without changing pitch (speed up/slow down)
- Pitch-shift audio without changing duration
- Low latency (~20-30ms) suitable for real-time TTS streaming
- Zero dependencies - WASM is bundled
- Works with Node.js and Bun
Installation
bun add sonic-wasm
# or
npm install sonic-wasmQuick Start
import { Sonic } from "sonic-wasm";
// Create a processor for 24kHz mono audio at 1.5x speed
const sonic = await Sonic.create({
sampleRate: 24000,
numChannels: 1,
speed: 1.5,
});
// Process audio (Float32Array)
const output = sonic.process(inputSamples);
// Flush remaining samples when done
const remaining = sonic.flush();
// Clean up
sonic.destroy();API
Sonic.create(options)
Creates a new Sonic processor instance.
interface SonicOptions {
sampleRate: number; // Sample rate in Hz (e.g., 24000, 44100)
numChannels?: number; // Number of channels (default: 1)
speed?: number; // Playback speed (default: 1.0)
pitch?: number; // Pitch factor (default: 1.0)
rate?: number; // Rate factor (default: 1.0)
volume?: number; // Volume (default: 1.0)
}
const sonic = await Sonic.create(options);sonic.process(input: Float32Array): Float32Array
Process audio samples. Returns time-stretched/pitch-shifted output.
For streaming, call repeatedly with chunks of audio. Output length varies based on speed setting.
sonic.flush(): Float32Array
Flush any remaining buffered samples. Call this when you're done processing to get the final audio.
sonic.setSpeed(speed: number)
Change playback speed without affecting pitch.
0.5= half speed (slower)1.0= normal speed2.0= double speed (faster)
Range: 0.05 to 20.0
sonic.setPitch(pitch: number)
Change pitch without affecting duration.
0.5= one octave down1.0= normal pitch2.0= one octave up
Range: 0.05 to 20.0
sonic.setRate(rate: number)
Change both speed and pitch together (like changing tape speed).
sonic.setVolume(volume: number)
Adjust output volume. 1.0 = normal.
sonic.setQuality(quality: 0 | 1)
0= optimized for low latency1= optimized for higher quality
sonic.samplesAvailable(): number
Returns the number of output samples available to read.
sonic.destroy()
Free all resources. Must be called when done.
Examples
Speed Up TTS Audio
import { Sonic } from "sonic-wasm";
const sonic = await Sonic.create({
sampleRate: 24000,
speed: 1.3, // 30% faster
});
const spedup = sonic.process(ttsAudio);
const final = sonic.flush();
sonic.destroy();Streaming (Low Latency)
Process audio in small chunks for real-time applications:
import { Sonic } from "sonic-wasm";
const sonic = await Sonic.create({
sampleRate: 24000,
speed: 1.5,
});
// Process 20ms chunks as they arrive
const chunkSize = 480; // 20ms at 24kHz
for (const chunk of audioChunks) {
const output = sonic.process(chunk);
if (output.length > 0) {
playAudio(output);
}
}
// Don't forget final samples
const remaining = sonic.flush();
if (remaining.length > 0) {
playAudio(remaining);
}
sonic.destroy();Pitch Shift Without Speed Change
import { Sonic } from "sonic-wasm";
const sonic = await Sonic.create({
sampleRate: 44100,
speed: 1.0, // Keep original duration
pitch: 1.5, // Shift pitch up ~7 semitones
});
const pitched = sonic.process(audio);
const final = sonic.flush();
sonic.destroy();Dynamic Speed Adjustment
import { Sonic } from "sonic-wasm";
const sonic = await Sonic.create({ sampleRate: 24000 });
// Start at normal speed
sonic.setSpeed(1.0);
let output1 = sonic.process(chunk1);
// Speed up mid-stream
sonic.setSpeed(2.0);
let output2 = sonic.process(chunk2);
sonic.destroy();Building from Source
Requires Emscripten to rebuild the WASM.
# Install Emscripten (one-time)
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk && ./emsdk install latest && ./emsdk activate latest
source emsdk_env.sh
# Build
bun run buildLicense
Apache-2.0 (same as libsonic)
