Audio I/O
Getting audio in and out is where a browser-native engine earns its keep. The
audioio namespace wraps the Web Audio decode path behind a single load call,
and the encodeWav / decodeWav pair is one pure-JavaScript WAV codec that runs
identically in Node, workers, and browsers. Between them you can synthesize test
signals, decode a real file, run analysis, and write the result back out —
without pulling in a native dependency.
The distinction to keep in mind: audioio.load / play / stop are
browser-only (they touch window.AudioContext and fetch), while the signal
math — tone, chirp, clicks, resample, lpc, and the WAV codec — is pure
and Node-safe.
Key functions
Section titled “Key functions”audioio.load(url, { sr?, mono?, offset?, duration? })— fetch + decode a URL to aFloat32Array(browser only).audioio.play({ loop? })/audioio.stop()— Web Audio playback of the currently loaded buffer.audioio.tone(frequency, opts?)/audioio.chirp(...)/audioio.clicks(...)— deterministic signal generators for tests and demos.audioio.resample,audioio.toMono,audioio.lpc,audioio.autocorrelate,audioio.zeroCrossings,audioio.muCompress/audioio.muExpand— pure DSP utilities.encodeWav(channels, sampleRate)/decodeWav(buffer)— the one canonical WAV codec.encodeWavtakes an array of channel arrays and returns anArrayBuffer;decodeWavreturns{ channels, sampleRate }.file.*— the browser convenience layer:example,listExamples,loadFile,saveAudio.fileio.*—stream(chunked reader),find_files,cite.
Example
Section titled “Example”import { audioio, encodeWav, decodeWav } from 'pleco-xa'
// Browser: fetch + decodeAudioData behind one call, resampled to 22.05 kHz monoconst y = await audioio.load('/audio/loop.wav', { sr: 22050, mono: true })
// Anywhere (Node, worker, browser): the one canonical WAV codec.// encodeWav takes an array of channels; decodeWav returns { channels, sampleRate }.const wav = encodeWav([y], 22050) // 16-bit PCM interleaved ArrayBufferconst { channels, sampleRate } = decodeWav(wav)
// Pure signal generators — no AudioContext required, so they run in Node tooconst test = audioio.tone(440, { sr: 22050, duration: 1 })- One codec, everywhere.
encodeWav/decodeWavare pureArrayBuffer/DataViewcode, so they behave identically in Node, browsers, and workers. Encode is 16-bit PCM interleaved; decode handles PCM 16/24/32-bit int and 32-bit float. The 16-bit round-trip max error is exactly1/32768. load(mono: false)concatenates channels flat. It does not return a 2-D or interleaved array — the channels are laid end to end. For per-channel work, decode withdecodeWavand readchannels[i].resampleis linear interpolation. It aliases on downsampling, so it is a convenience path, not a band-limited resampler — don’t use it where fidelity matters.- Two correct decoders can disagree by 1 LSB. Chrome’s
decodeAudioDatamaps int16 → float ass / 32768in both directions, whiledecodeWavusess / 0x7ffffor positives. Any bitwise assertion must reference the same decoder that produced the data. fileio.stream()is decode-whole-then-chunk, not true streaming: memory is O(file),blockLengthcounts samples and advances byhopLength(so blocks can overlap). It is a sample-block reader, not a frame-block stream — treat it as a chunked reader.- Codec coverage is an explicit exception. Native WAV is built in; other
codecs come from the browser’s
decodeAudioDataor, in Node, an injectable decoder hook.tone/chirp/clicks/ mu-law /lpcare all golden-verified.
See the API reference for full signatures and defaults.