Skip to content

PeshoVurtoleta/lite-audio-pool

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@zakkster/lite-audio-pool

npm version npm bundle size npm downloads npm total downloads TypeScript Zero Dependencies License: MIT

🎧 What is lite-audio-pool?

@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.

πŸš€ Install

npm i @zakkster/lite-audio-pool

πŸ•ΉοΈ Quick Start

import { 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();

🧠 Why This Exists

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.

πŸ“Š Comparison

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

βš™οΈ API

new AudioPool(ctx, audioBuffer, spriteMap, capacity?)

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)

play(spriteId, volume?, pan?, pitch?)

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.

stop(channelId)

Stops a specific channel with a 20ms fade. Safe to call with invalid IDs.

stopAll()

Stops all active channels. Useful for scene transitions or pause screens.

Sprite Map Format

{
  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.

πŸ§ͺ Benchmark

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

πŸ”§ Internal Architecture

                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚         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.

πŸ“¦ TypeScript

Full TypeScript declarations included in AudioPool.d.ts.

πŸ“š LLM-Friendly Documentation

See llms.txt for AI-optimized metadata and usage examples.

License

MIT

About

Zero-GC Web Audio sound sprite pool. Voice stealing with 20ms anti-pop fade, pitch shifting, stereo pan.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors