WAV (RIFF) file encoding and decoding utilities using binary structures.
This module provides coders for WAV file structures including:
- RIFF chunk with WAVE format identification
- Format chunk supporting multiple audio formats (PCM, IEEE float, A-law, μ-law, extensible)
- Data chunk with raw audio samples
- Optional chunks (fact, LIST)
- Complete WAV file structure (RIFF, fmt, data)
Chunk sizes are taken from the structure as given; they are never recomputed,
and payload lengths are driven by the chunkSize field of their chunk.
Basic WAV file encoding and decoding
Basic WAV file encoding and decoding
import { assertEquals } from "@std/assert"; import { wavFile } from "@binstruct/wav"; const wavCoder = wavFile(); const testWav = { riff: { chunkId: "RIFF" as const, chunkSize: 1038, // total file size minus the 8-byte RIFF header format: "WAVE" as const }, fmt: { chunkId: "fmt " as const, chunkSize: 18, // 16 PCM fields plus the 2-byte cbSize audioFormat: 1, // PCM numChannels: 1, // Mono sampleRate: 44100, byteRate: 88200, blockAlign: 2, bitsPerSample: 16, cbSize: 0 }, data: { chunkId: "data" as const, chunkSize: 1000, audioData: new Array(1000).fill(0) } }; const buffer = new Uint8Array(2048); const bytesWritten = wavCoder.encode(testWav, buffer); const [decodedWav, bytesRead] = wavCoder.decode(buffer); assertEquals(bytesRead, bytesWritten); assertEquals(bytesWritten, 1046); // 12 (RIFF) + 26 (fmt) + 1008 (data) assertEquals(decodedWav.riff.chunkId, "RIFF"); assertEquals(decodedWav.riff.format, "WAVE"); assertEquals(decodedWav.fmt.audioFormat, 1); assertEquals(decodedWav.fmt.numChannels, 1); assertEquals(decodedWav.fmt.sampleRate, 44100); assertEquals(decodedWav.data.audioData.length, 1000);
IEEE float format
IEEE float format
import { assertEquals } from "@std/assert"; import { wavFile } from "@binstruct/wav"; const floatWavCoder = wavFile(); const floatWav = { riff: { chunkId: "RIFF", chunkSize: 838, // total file size minus the 8-byte RIFF header format: "WAVE" }, fmt: { chunkId: "fmt ", chunkSize: 18, audioFormat: 3, // IEEE Float numChannels: 2, // Stereo sampleRate: 48000, byteRate: 384000, blockAlign: 8, bitsPerSample: 32, cbSize: 0 }, data: { chunkId: "data", chunkSize: 800, audioData: new Array(800).fill(0) } }; const buffer = new Uint8Array(2048); const bytesWritten = floatWavCoder.encode(floatWav, buffer); const [decoded, bytesRead] = floatWavCoder.decode(buffer); assertEquals(bytesRead, bytesWritten); assertEquals(bytesWritten, 846); // 12 (RIFF) + 26 (fmt) + 808 (data) assertEquals(decoded.fmt.audioFormat, 3); assertEquals(decoded.fmt.numChannels, 2); assertEquals(decoded.data.audioData.length, 800);