MPEG audio frame header (MP3) encoding and decoding.
Every MP3 frame opens with a 4-byte, bit-packed header. All fields are MSB-first within the 32 bits:
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Frame Sync (11) |Ver|Lyr|P| Bitrate |SRat| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Pd|Pr| ChMode|ModeExt|Cp|Or| Emph| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Frame Sync (11 bits) — always all-ones (
MP3_FRAME_SYNC), marking the start of a frame. - Ver (
mpegVersion, 2 bits) — MPEG version. SeeMP3_MPEG_VERSION. - Lyr (
layer, 2 bits) — MPEG layer. SeeMP3_LAYER. - P (
protectionAbsent, 1 bit) —1means no CRC follows the header,0means a 16-bit CRC follows (not covered by this coder). - Bitrate (
bitrateIndex, 4 bits) — index into a version/layer-specific bitrate table. This package does not resolve it to a kbps value. - SRat (
samplingRateIndex, 2 bits) — index into a version-specific sample-rate table. This package does not resolve it to a Hz value. - Pd (
padding, 1 bit) —1if the frame carries one extra padding slot, used to make the average bitrate match exactly. - Pr (
privateBit, 1 bit) — format-defined, not used by the decoder. - ChMode (
channelMode, 2 bits) — channel mode. SeeMP3_CHANNEL_MODE. - ModeExt (
modeExtension, 2 bits) — only meaningful whenchannelModeis joint stereo; selects which joint-stereo technique applies. - Cp (
copyright, 1 bit) —1if the material is copyrighted. - Or (
original, 1 bit) —1if this is the original media. - Emph (
emphasis, 2 bits) — de-emphasis to apply on playback.
This package covers the 4-byte frame header only. It does not compute frame length, resolve bitrate/sample-rate table indices to real values, or parse ID3 tags, side information, or audio data — see the package description for the full v0.0.1 scope.
Round-trip a frame header
Round-trip a frame header
import { assertEquals } from "@std/assert"; import { MP3_CHANNEL_MODE, MP3_FRAME_HEADER_SIZE, MP3_FRAME_SYNC, MP3_LAYER, MP3_MPEG_VERSION, mp3FrameHeader, } from "@binstruct/mp3"; const coder = mp3FrameHeader(); const header = { frameSync: MP3_FRAME_SYNC, mpegVersion: MP3_MPEG_VERSION.MPEG_1, layer: MP3_LAYER.LAYER_3, protectionAbsent: 1, bitrateIndex: 9, samplingRateIndex: 0, padding: 0, privateBit: 0, channelMode: MP3_CHANNEL_MODE.STEREO, modeExtension: 0, copyright: 0, original: 0, emphasis: 0, }; const buffer = new Uint8Array(MP3_FRAME_HEADER_SIZE); const written = coder.encode(header, buffer); const [decoded, read] = coder.decode(buffer); assertEquals(written, MP3_FRAME_HEADER_SIZE); assertEquals(read, MP3_FRAME_HEADER_SIZE); assertEquals(decoded, header);