✳ OMNIVIEWER MP3 viewer MP3 generator ← back

Anatomy of an MP3 file

An MP3 looks like a single opaque blob, but it is really two things glued together: a block of ID3 metadata and a long run of independent MPEG audio frames. This is a byte-level tour of both — for MPEG-1, MPEG-2 and MPEG-2.5 Layer III — with a short history of how the format took over the world.

On this page History File layout The frame header Per-version anatomy ID3 tags The Xing/Info header

A short history of the MP3

MP3 — formally MPEG-1/2 Audio Layer III — grew out of psychoacoustic research at Germany's Fraunhofer IIS, led by Karlheinz Brandenburg, together with the University of Erlangen and partners across Europe. The idea was radical for the late 1980s: throw away the parts of an audio signal the human ear can't hear (frequencies masked by louder ones) and encode only what's left, shrinking CD-quality audio roughly tenfold.

DRM-free, thanks in large part to Amazon. For years, legal downloads were wrapped in copy-protection (DRM) that locked songs to one store's players. That changed in September 2007 when Amazon.com launched Amazon MP3 — the first major online music store to sell DRM-free MP3s, and the first to offer that catalogue from all four major record labels. Buyers finally got a plain .mp3 they could play anywhere, on any device, forever. It pushed the whole industry toward unrestricted downloads (Apple's iTunes went fully DRM-free in 2009).

The last of the MP3 patents expired around 2017, and Fraunhofer ended its licensing program that April — making MP3 not just ubiquitous but fully free to implement. Newer codecs (AAC, Opus) are more efficient, but MP3's universal compatibility keeps it everywhere.

The overall file layout

Read from offset 0, a typical MP3 is:

┌───────────────────────────────────────────────┐
│ ID3v2 tag      "ID3" + version + size + frames │  ← optional, at the very start
│   TIT2 title · TPE1 artist · TALB album · APIC │    (title/artist/album/cover art)
├───────────────────────────────────────────────┤
│ MPEG audio frame  #0   [Xing/Info VBR header]  │  ← first frame often holds the
│ MPEG audio frame  #1                           │    duration/VBR table
│ MPEG audio frame  #2                           │
│        … thousands of independent frames …     │
│ MPEG audio frame  #N                           │
├───────────────────────────────────────────────┤
│ ID3v1 tag      "TAG" + 125 bytes               │  ← optional, the last 128 bytes
└───────────────────────────────────────────────┘

The ID3v2 block and the ID3v1 trailer are both optional. The audio itself is just a stream of self-describing frames — each frame carries its own header, so a player can start decoding from almost anywhere. That's exactly why streaming and “seek by scanning for the next sync word” work.

Open any MP3 in the OmniViewer hex view and you'll see the 49 44 33 (“ID3”) magic at offset 0, then FF Fx sync bytes where the first audio frame begins. The METADATA tab decodes the ID3 frames for you.

The 32-bit frame header

Every audio frame begins with a four-byte header. All 32 bits:

AAAAAAAA  AAABBCCD  EEEEFFGH  IIJJKLMM

A (11)  frame sync — all 1s (bytes read FF Ex/Fx)
B (2)   MPEG version   00=2.5  01=reserved  10=MPEG-2  11=MPEG-1
C (2)   layer          01 = Layer III (MP3)
D (1)   protection     0 = a 16-bit CRC follows the header
E (4)   bitrate index  → looked up in a per-version table
F (2)   sample-rate index → per-version table (see below)
G (1)   padding        1 = frame is 1 byte longer (keeps avg bitrate exact)
H (1)   private bit
I (2)   channel mode   00 stereo · 01 joint · 10 dual · 11 mono
J (2)   mode extension (joint-stereo params)
K (1)   copyright   L (1) original   M (2) emphasis

Because bitrate and sample rate live in every header, a file can switch bitrate frame to frame — that's VBR (variable bitrate). The header also fixes how long the frame is:

MPEG-1 Layer III:      frameLength = 144 × bitrate / sampleRate + padding
MPEG-2 / 2.5 Layer III: frameLength =  72 × bitrate / sampleRate + padding

The 144 vs 72 is not arbitrary: it's samplesPerFrame / 8. An MPEG-1 frame carries 1152 samples; an MPEG-2 or 2.5 frame carries 576. Fewer samples per frame is how the lower sample-rate versions keep frames small.

Anatomy per MPEG version

Layer III comes in three flavours. They share the header format above but differ in the sample rates they allow, how many samples a frame holds, and the size of the per-frame “side information” block:

PropertyMPEG-1 Layer IIIMPEG-2 Layer IIIMPEG-2.5 Layer III
Version bits (B)111000
Sample rates32 · 44.1 · 48 kHz16 · 22.05 · 24 kHz8 · 11.025 · 12 kHz
Samples per frame1152576576
Bitrates (kbps)32–3208–1608–160
Side info — stereo32 bytes17 bytes17 bytes
Side info — mono17 bytes9 bytes9 bytes
Length constant1447272
StandardISO/IEC 11172-3ISO/IEC 13818-3Fraunhofer extension

MPEG-2.5 is worth a note: it is not part of any ISO standard. It's a Fraunhofer extension that reuses the reserved version bits (00) to reach very low sample rates (down to 8 kHz) for speech and ultra-low-bitrate streams. Most decoders support it anyway.

Inside a single frame

┌────────┬──────┬────────────┬──────────────────────────┐
│ header │ CRC  │ side info  │ main data (Huffman-coded)  │
│ 4 B    │ 0/2B │ 9–32 B     │ scalefactors + frequencies │
└────────┴──────┴────────────┴──────────────────────────┘
         ▲ present only if the protection bit (D) = 0

The side info tells the decoder how to read the main data (bit reservoir pointer, scalefactor layout, Huffman table selection). A frame whose side info and main data are all zero decodes to silence — which is exactly the trick the MP3 generator uses to build valid files of any size.

ID3 tags: the metadata

The audio frames carry no title or artist — that's what ID3 is for. Two incompatible schemes coexist:

ID3v1 — 128 bytes at the end

offset  bytes  field
   0      3    "TAG" magic
   3     30    title
  33     30    artist
  63     30    album
  93      4    year
  97     30    comment   (last 2 bytes may encode a track number → "ID3v1.1")
 127      1    genre     (index into a fixed list)

Fixed-width, ASCII/Latin-1, no room for cover art — a relic, but still written by many tools. Because it's a fixed 128-byte trailer, a reader only has to look at the last 128 bytes.

ID3v2 — a rich block at the start

ID3v2 (v2.2/2.3/2.4) sits before the audio and is a container of frames, each a four-character ID plus a size and payload:

"ID3"  ver(2)  flags(1)  size(4, "synchsafe" — 7 bits per byte)
  then repeating frames:
    TIT2  title          TPE1  artist        TALB  album
    TPE2  album artist   TRCK  track         TCON  genre
    TYER/TDRC  year      COMM  comment       APIC  attached picture (cover art)

The size is synchsafe — only the low 7 bits of each byte are used — so a tag's length can never accidentally contain the FF byte that would look like a frame sync. OmniViewer's METADATA tab reads and rewrites these v2.3/v2.4 text frames; the generator writes a fresh v2.4 tag.

The Xing / Info / VBRI header

One more wrinkle: for a variable-bitrate file you can't work out the duration by dividing file size by bitrate — the bitrate changes. So encoders put a special metadata block inside the first audio frame (which is otherwise silent):

This is why a player can show an accurate track length and seek instantly even in a VBR MP3. LAME also appends a small “LAME tag” here recording the encoder version and settings — the LAME3.100 strings you'll spot scattered through the raw bytes of many files.

Inspect a real MP3 →Drop a file into the viewer: hex, ID3 metadata, raw strings. Generate an MP3 →Build a valid silent MP3 of any size, up to 2 GB.