/** * Minimal ambient WebCodecs declarations. * * TypeScript 5.9's bundled lib.dom.d.ts does NOT yet ship the WebCodecs audio types * (`AudioDecoder`, `EncodedAudioChunk`, `AudioData`, `AudioDecoderConfig`), and this repo has no * package.json / node_modules to pull in `@types/dom-webcodecs`. Rather than add a dependency * toolchain for one feature, this declares exactly the slice of the WebCodecs surface the Opus * streaming decoder uses — nothing more. The shapes follow the W3C WebCodecs spec. * * These are runtime-optional: `AudioDecoder` is absent on Safari < 16.4 and older Firefox, so every * use site guards on `typeof AudioDecoder !== 'undefined'` before touching it (the capability gate). */ interface AudioDecoderConfig { codec: string; sampleRate: number; numberOfChannels: number; /** Codec-specific setup bytes. For Opus this is the OpusHead identification header. */ description?: BufferSource; } interface AudioDecoderSupport { supported: boolean; config: AudioDecoderConfig; } type AudioSampleFormat = 'u8' | 's16' | 's24' | 's32' | 'f32' | 'u8-planar' | 's16-planar' | 's24-planar' | 's32-planar' | 'f32-planar'; interface AudioDataCopyToOptions { planeIndex: number; frameOffset?: number; frameCount?: number; format?: AudioSampleFormat; } interface AudioData { readonly format: AudioSampleFormat | null; readonly sampleRate: number; readonly numberOfFrames: number; readonly numberOfChannels: number; readonly duration: number; /** Presentation timestamp in microseconds. */ readonly timestamp: number; allocationSize(options: AudioDataCopyToOptions): number; copyTo(destination: BufferSource, options: AudioDataCopyToOptions): void; close(): void; } interface EncodedAudioChunkInit { type: 'key' | 'delta'; /** Presentation timestamp in microseconds. */ timestamp: number; duration?: number; data: BufferSource; } declare class EncodedAudioChunk { constructor(init: EncodedAudioChunkInit); readonly type: 'key' | 'delta'; readonly timestamp: number; readonly duration: number | null; readonly byteLength: number; } interface AudioDecoderInit { output: (data: AudioData) => void; error: (error: DOMException) => void; } type CodecState = 'unconfigured' | 'configured' | 'closed'; declare class AudioDecoder { constructor(init: AudioDecoderInit); readonly state: CodecState; readonly decodeQueueSize: number; configure(config: AudioDecoderConfig): void; decode(chunk: EncodedAudioChunk): void; flush(): Promise; reset(): void; close(): void; static isConfigSupported(config: AudioDecoderConfig): Promise; }