/** * Layer III side information and the bit reservoir. * * ## The bit reservoir, and why decoding is not frame-by-frame * * An MP3 frame has a fixed byte length set by its bitrate, but the audio in it * does not need a fixed number of bits. A quiet passage leaves bits unused; a * dense one needs more than its frame allows. Layer III lets a frame *borrow* * the unused tail of earlier frames — the "bit reservoir". * * The practical consequence: a frame's Huffman data usually does not start * inside that frame. `main_data_begin` says how many bytes *backwards* from the * end of this frame's header the data actually begins. So a decoder must keep a * rolling buffer of recent frame payloads, and cannot decode frame N without * having seen the frames before it. * * This is also why seeking into the middle of an MP3 produces a brief artefact, * and why the first frame after a seek is usually discarded. */ import type { FrameHeader } from './frame.js'; /** Per-granule, per-channel coding parameters. */ export interface GranuleInfo { /** Bits of main data used by this granule and channel. */ part2_3_length: number; /** Number of Huffman-coded value pairs in the "big values" region. */ bigValues: number; /** Quantizer step size for the whole granule. */ globalGain: number; /** Selects the scalefactor bit-length pair. */ scalefacCompress: number; /** True when this granule does not use a single long window. */ windowSwitching: boolean; /** 0 = normal long, 1 = long-to-short, 2 = three short, 3 = short-to-long. */ blockType: number; /** True when the two lowest sub-bands stay long while the rest are short. */ mixedBlock: boolean; /** Huffman table per region. */ tableSelect: [number, number, number]; /** Extra gain per short sub-block. */ subblockGain: [number, number, number]; /** Scalefactor band where region 0 ends. */ region0Count: number; /** Scalefactor band where region 1 ends. */ region1Count: number; /** Apply the high-frequency emphasis in PRETAB. */ preflag: boolean; /** Scalefactor multiplier: 0.5 when clear, 1.0 when set. */ scalefacScale: number; /** Which table decodes the count1 region. */ count1TableSelect: number; } export interface SideInfo { /** Bytes to look backwards for the start of this frame's main data. */ mainDataBegin: number; /** Scalefactor selection info: which bands are shared between granules. */ scfsi: number[][]; /** `[granule][channel]`. MPEG-1 has two granules; MPEG-2/2.5 has one. */ granules: GranuleInfo[][]; } /** * Parses the side information block that follows a frame header. * * MPEG-2 and 2.5 use a different, smaller layout than MPEG-1: one granule * instead of two, no `scfsi`, and an extra `intensity_stereo` flag. */ export declare function parseSideInfo(data: Uint8Array, offset: number, header: FrameHeader): SideInfo; /** * Rolling buffer of recent frame payloads, so `main_data_begin` can reach back * into earlier frames. * * The specification caps the look-back at 511 bytes (MPEG-1), so a buffer a * little larger than that is always sufficient. Older bytes are discarded, which * bounds memory regardless of file length. */ export declare class BitReservoir { #private; constructor(capacity?: number); /** Bytes currently held. */ get length(): number; /** Discards everything, e.g. after a seek. */ reset(): void; /** Appends one frame's main-data payload. */ push(data: Uint8Array): void; /** * Returns the main data for a frame, given its `main_data_begin`. * * Returns `null` when the reservoir does not yet hold enough history — normal * for the first frames of a file, and after a seek. The caller should skip * those frames rather than treat it as an error. */ read(mainDataBegin: number, frameData: Uint8Array): Uint8Array | null; }