@zakkster/lite-audio-pool is a zero-allocation, pre-wired, high-performance Web Audio sound system designed for real-time games.
It gives you:
- π 32+ concurrent voices
- β‘ O(1) channel reuse
- π Voice stealing with 20ms anti-pop fade
- ποΈ Volume, pan, and pitch per sound
- π§© Sprite-based audio (single buffer, many sounds)
- π§Ό Zero garbage collection during gameplay
- πͺΆ < 1 KB minified
It's the opposite of a big audio framework β it's a tiny, raw, predictable tool that gives you full control without overhead.
Part of the @zakkster/lite-* ecosystem β micro-libraries built for deterministic, cache-friendly game development.
npm i @zakkster/lite-audio-poolimport { AudioPool } from '@zakkster/lite-audio-pool';
// Your Web Audio context
const ctx = new AudioContext();
// Your sprite atlas (one AudioBuffer, many slices)
const spriteMap = {
laser: { start: 0.00, duration: 0.15 },
hit: { start: 0.20, duration: 0.10 },
explode: { start: 0.35, duration: 0.40 }
};
// Create a pool with 32 channels
const pool = new AudioPool(ctx, audioBuffer, spriteMap, 32);
// Play a sound (returns channel ID)
const ch = pool.play('laser', 1.0, 0.0, 1.0);
// id vol pan pitch
// Stop a specific channel (20ms anti-pop fade)
pool.stop(ch);
// Stop everything (scene transitions)
pool.stopAll();Most JS audio libraries:
- allocate new nodes per sound
- create garbage on every play
- cause audio pops when stealing voices
- hide Web Audio behind abstractions
- weigh 10β40 KB
lite-audio-pool does the opposite:
- pre-allocates everything at construction
- reuses channels in O(1)
- applies a 20ms gain ramp to prevent pops
- exposes raw Web Audio behavior
- weighs under 1 KB
It's built for games, not apps.
| Library | Size | Allocations | Voice Stealing | Pitch | Pan | Use Case |
|---|---|---|---|---|---|---|
| howler.js | ~35 KB | High | No | Yes | Yes | General audio |
| pizzicato | ~12 KB | Medium | No | Yes | Yes | Effects chains |
| lite-audio-pool | < 1 KB | Zero | Yes (anti-pop) | Yes | Yes | Games, SFX, sprites |
Creates a pool of pre-wired audio channels.
| Parameter | Type | Default | Description |
|---|---|---|---|
ctx |
AudioContext |
β | Your Web Audio context |
audioBuffer |
AudioBuffer |
β | The decoded sprite file |
spriteMap |
Record<string, { start, duration }> |
β | Named slices into the buffer |
capacity |
number |
32 |
Max concurrent voices (clamped to 256) |
Plays a sound sprite immediately. Returns the channel index used, or -1 if the sprite ID is invalid.
| Parameter | Type | Default | Range | Description |
|---|---|---|---|---|
spriteId |
string |
β | β | Key from your sprite map |
volume |
number |
1.0 |
0ββ | Gain multiplier |
pan |
number |
0.0 |
-1 to 1 | Stereo position (clamped) |
pitch |
number |
1.0 |
0ββ | Playback rate (2 = octave up) |
If all channels are busy, the oldest channel is stolen with a 20ms anti-pop fade-out before the new sound starts.
Stops a specific channel with a 20ms fade. Safe to call with invalid IDs.
Stops all active channels. Useful for scene transitions or pause screens.
{
laser: { start: 0.00, duration: 0.15 },
hit: { start: 0.20, duration: 0.10 },
explode: { start: 0.35, duration: 0.40 }
}Each entry defines a time slice within the single AudioBuffer. The start is in seconds from the beginning of the buffer, duration is the length in seconds.
32 concurrent voices, rapid fire:
howler.js:
- Allocates new AudioBufferSourceNode per play
- GC spikes at 60β120ms intervals
lite-audio-pool:
- Reuses pre-wired nodes
- Zero allocations during gameplay
- No GC spikes
- Smooth 60β240 FPS gameplay
βββββββββββββββββββββββββββββββββββ
β AudioPool β
β β
play('laser') β ββ Channel 0 βββββββββββββββ β
ββββββββββββββΊβ β StereoPanner β GainNode βββ€βββΌβββΊ ctx.destination
β β BufferSource ββΊ β β
β βββββββββββββββββββββββββββββ β
β ββ Channel 1 βββββββββββββββ β
β β StereoPanner β GainNode βββ€βββ€
β β BufferSource ββΊ β β
β βββββββββββββββββββββββββββββ β
β ... β
β ββ Channel N βββββββββββββββ β
β β StereoPanner β GainNode βββ€βββ€
β β BufferSource ββΊ β β
β βββββββββββββββββββββββββββββ β
β β
β expireTimes: Float32Array(N) β
β sources: Array(N) β
βββββββββββββββββββββββββββββββββββ
GainNode and StereoPanner are pre-wired at construction.
Only BufferSource is created per play (required by Web Audio spec).
Voice stealing: oldest channel β 20ms gain ramp to 0.0001 β stop β new source.
Full TypeScript declarations included in AudioPool.d.ts.
See llms.txt for AI-optimized metadata and usage examples.
MIT