@soundtouchjs/core
v1.0.7
Published
An audio processing library for manipulating Web Audio Contexts
Maintainers
Readme
@soundtouchjs/core
Core audio processing library for real-time pitch shifting, tempo adjustment, and rate transposition using the Web Audio API. A TypeScript rewrite of the SoundTouch audio processing library.
Installation
npm install @soundtouchjs/coreUsage
PitchShifter (ScriptProcessorNode)
The simplest way to get started. PitchShifter wraps a ScriptProcessorNode and handles buffering, playback tracking, and parameter control.
import { PitchShifter } from '@soundtouchjs/core';
const audioCtx = new AudioContext();
const gainNode = audioCtx.createGain();
gainNode.connect(audioCtx.destination);
const response = await fetch('/audio.mp3');
const buffer = await response.arrayBuffer();
const audioBuffer = await audioCtx.decodeAudioData(buffer);
const shifter = new PitchShifter(audioCtx, audioBuffer, 16384);
shifter.tempo = 1.2;
shifter.pitch = 0.9;
shifter.pitchSemitones = -2;
shifter.on('play', (detail) => {
console.log(detail.formattedTimePlayed); // "1:23"
console.log(detail.percentagePlayed); // 42.5
});
// Connect to start playback
shifter.connect(gainNode);
// Disconnect to pause
shifter.disconnect();Note:
ScriptProcessorNodeis deprecated in the Web Audio spec. For new projects, consider using@soundtouchjs/audio-workletwhich provides anAudioWorklet-based implementation.
Low-level API
All internal components are exported for advanced use cases:
import {
SoundTouch,
SimpleFilter,
WebAudioBufferSource,
FifoSampleBuffer,
} from '@soundtouchjs/core';
const st = new SoundTouch();
st.pitch = 1.5;
st.tempo = 0.8;
const source = new WebAudioBufferSource(audioBuffer);
const filter = new SimpleFilter(source, st);
// Pull processed samples
const outputBuffer = new Float32Array(4096);
const framesRead = filter.extract(outputBuffer, 2048);Key classes
| Export | Description |
| ---------------------- | -------------------------------------------------------------------------- |
| SoundTouch | Main processing engine — set pitch, tempo, rate, or pitchSemitones |
| PitchShifter | High-level wrapper using ScriptProcessorNode with playback events |
| SimpleFilter | Pulls samples through a SoundTouch pipe from a source |
| WebAudioBufferSource | Adapter from AudioBuffer to the internal sample source interface |
| FifoSampleBuffer | Resizable interleaved sample buffer (ES2024 ArrayBuffer) |
| getWebAudioNode | Creates a ScriptProcessorNode wired to a SimpleFilter |
| Stretch | Time-stretch processor (used internally by SoundTouch) |
| RateTransposer | Sample rate transposer (used internally by SoundTouch) |
What's changed in v0.4
- Monorepo: Now published as
@soundtouchjs/corefrom an Nx monorepo (wassoundtouchjs) - TypeScript: Full rewrite — strict mode, zero
any, complete type exports - ESM only: Pure ES modules targeting ES2024 (
import/export, no CommonJS) - ES2024 buffers:
FifoSampleBufferuses resizableArrayBufferfor zero-allocation growth - Optimized internals: Scratch buffer reuse in
SimpleFilter, dirty-flag overlap buffers inStretch - Zero runtime dependencies
License
LGPL-2.1 — see LICENSE for details.
Key switching and pitch control
Changing the musical key of playback is handled by the pitchSemitones parameter. Each integer step corresponds to one semitone (half-step) on the chromatic scale. For example:
pitchSemitones = 2shifts the key up a whole steppitchSemitones = -3shifts down a minor third
The effective pitch is calculated as:
pitch * 2^(pitchSemitones / 12)This lets you combine continuous pitch control (pitch) with discrete key changes (pitchSemitones).
For most musical applications, set pitchSemitones to the desired interval and leave pitch at 1.0 unless you want fine-tuning within a semitone.
See @soundtouchjs/audio-worklet for AudioWorklet-based usage.
