FLAC Is Now RFC 9639: A Plain-English Tour of the Specification
In December 2024 the IETF published the Free Lossless Audio Codec (FLAC) as RFC 9639, written by M.Q.C. van Beurden and A. Weaver. The RFC Editor's record lists it as a Standards Track document with Proposed Standard status. The abstract says FLAC is free in the sense that its specification is open and its reference implementation is open source, that it has low complexity compared with other lossless audio formats, and that decoders have been implemented independently on many platforms.
For anyone who works with PCM, the RFC is also a compact description of how raw samples are packaged and protected. This guide walks through the parts that matter and quotes the numbers directly from the document, with section numbers in brackets so you can check them.
What FLAC Can Hold [Section 1]
RFC 9639 says FLAC files and streams can code for PCM audio within these limits:
| Property | Range |
|---|---|
| Channels | 1 to 8 |
| Sample rate | 1 to 1,048,575 Hz |
| Bit depth | 4 to 32 bits |
The RFC adds that most tools have been optimised for CD audio, which is PCM with 2 channels, a 44.1 kHz sample rate and 16-bit samples. The sample-rate limit is simply the largest number that fits in the 20-bit sample-rate field of the STREAMINFO block (our arithmetic: 2²⁰ − 1).
Two rules matter if you start from raw PCM:
- Samples must be signed [Sections 1 and 5]. Unsigned PCM, such as 8-bit data where silence is stored as 128, has to be converted first. The RFC describes copying each value into a signed integer with enough range and then subtracting half of the unsigned range, which for 8-bit audio means subtracting 128 (our arithmetic). Without that step, the RFC says, compression will not be reasonable.
- Built for PCM [Section 1]. The RFC says the format is not suited to compressing audio that is not PCM, although it notes elsewhere that the format can also store other digital signals and that the document uses audio terminology throughout [Section 2]. It also says every number in a FLAC bitstream is an integer and that there are no floating-point representations [Section 5], so the format describes integer samples only. Floating-point audio has to be converted to integers before FLAC can carry it.
How FLAC Shrinks PCM Without Changing a Sample [Section 4]
FLAC can be lossless because samples in audio signals tend to be highly correlated with their close neighbours [Section 1]. Unlike general-purpose compressors, it removes redundancy only in the very short term, looking back at 32 samples at most. A FLAC file is built in four steps, and decoding runs them in reverse:
- Blocking. The input is split into blocks of 16 to 65,535 samples, except that the last block may be shorter [Section 4.1].
- Interchannel decorrelation. For stereo, each block can be coded as independent channels, mid-side, left-side or side-right [Section 4.2].
- Prediction. Each channel in a block is stored as a constant value, verbatim samples, a fixed predictor (five fixed predictors, orders 0 to 4) or a linear predictor (orders 1 to 32) [Sections 4.3, 9.2.5 and 9.2.6].
- Residual coding. The prediction error is coded with Rice codes, using a 4-bit or 5-bit parameter, split into partitions that each have their own parameter [Section 4.4].
The mid-side step is the easiest to check by hand. The RFC defines mid as the sum of left and right shifted right by one bit, and side as left minus right. Take a left sample of 5 and a right sample of 2:
mid = (5 + 2) >> 1 = 3
side = 5 - 2 = 3
decode: mid << 1 = 6, and side is odd, so add 1 -> 7
left = (7 + 3) >> 1 = 5
right = (7 - 3) >> 1 = 2The bit lost by the right shift is not really lost. The bit shifted out of the sum is always the same as the lowest bit of the side value, because a sum and a difference of the same two numbers always have the same parity (our arithmetic). The decoder can therefore restore the missing bit from the side channel, which is what keeps mid-side lossless. The RFC also notes that the side channel needs one extra bit of bit depth, because subtracting two samples can produce a value twice as large as the maximum.
A related feature is wasted bits [Section 9.2.2]. Some audio, such as 14-bit data stored in 16-bit samples, has least-significant bits that are always zero. FLAC can signal how many there are, code the samples without them, and have the decoder shift them back in.
Reading a FLAC Header by Hand [Sections 6, 8.1 and 8.2]
A FLAC stream begins with the four-byte marker fLaC (hex 66 4C 61 43), followed by metadata blocks and then the audio frames. The first metadata block must be STREAMINFO. Each metadata block starts with a 4-byte header: one bit that says whether this is the last metadata block, seven bits for the block type (0 means STREAMINFO), and a 24-bit big-endian length that excludes the header itself.
The STREAMINFO block holds these fields, in this order [Table 3]:
| Field | Size |
|---|---|
| Minimum block size, in samples | 16 bits |
| Maximum block size, in samples | 16 bits |
| Minimum frame size, in bytes (0 means unknown) | 24 bits |
| Maximum frame size, in bytes (0 means unknown) | 24 bits |
| Sample rate, in Hz | 20 bits |
| Number of channels minus 1 | 3 bits |
| Bits per sample minus 1 | 5 bits |
| Total interchannel samples (0 means unknown) | 36 bits |
| MD5 checksum of the unencoded audio (0 means unknown) | 128 bits |
Those add up to 272 bits, or 34 bytes (our arithmetic), so the length field in a STREAMINFO block header is 34. All numbers in the bitstream are big-endian, except the field lengths inside Vorbis comments [Section 5].
Here is how to read the three packed fields. If STREAMINFO is the first block, the 4-byte marker, the 4-byte block header, the two 16-bit block sizes and the two 24-bit frame sizes take up the first 18 bytes. Bytes 18 to 21 (counting from zero) then hold the sample rate, channel count, bit depth and the start of the sample count. For CD audio, the sample rate 44,100 is hex 0AC44 in the 20-bit field, the stereo channel count is stored as 1 and the 16-bit depth is stored as 15, which packs into 0A C4 42 F0. The last hex digit belongs to the sample count, and is 0 for any file shorter than 2³² samples, which is about 27 hours at 44.1 kHz.
The same calculation for other common formats gives these bytes (our calculation from Table 3):
| Format | Bytes 18 to 21 |
|---|---|
| 44.1 kHz, stereo, 16-bit | 0A C4 42 F0 |
| 48 kHz, stereo, 24-bit | 0B B8 03 70 |
| 96 kHz, stereo, 24-bit | 17 70 03 70 |
| 16 kHz, mono, 16-bit | 03 E8 00 F0 |
| 8 kHz, mono, 16-bit | 01 F4 00 F0 |
To look at them on macOS or Linux, run this command:
xxd -s 18 -l 4 song.flacThis only works if the file begins with the fLaC marker and STREAMINFO is the first metadata block, which the RFC requires. We checked the offsets with that command on a hand-built header, not on a decoder-validated audio file.
The MD5 Checksum Is Raw PCM [Section 8.2]
STREAMINFO stores an MD5 checksum of the unencoded audio, which the RFC says lets a decoder detect an error in the audio data even when the bitstream itself is valid. It is computed over all samples of all channels, interleaved, signed and little-endian, with each sample padded to a whole number of bytes by sign extension if its bit depth is not a multiple of 8. A value of 0 means the checksum is unknown.
For 16-bit stereo, that description is exactly the byte stream of a headerless s16le PCM file, which is the format we work with in our FFmpeg guide. In other words, the checksum is stored in terms of the raw PCM, even though the compressed audio inside the file looks nothing like it.
FLAC protects the frames too. Each frame header ends with an 8-bit CRC [Section 6], and each frame ends with a 16-bit CRC that covers the whole frame including the sync code [Section 9.3]. The RFC lists a frame header or footer CRC that does not validate as invalid data, and says a decoder may stop decoding when it meets it.
Frames, Sync Codes and the Streamable Subset [Sections 6 and 7]
Each frame starts with a byte-aligned 15-bit sync code, which lets a decoder begin decoding at any place in the stream. After finding a sync code, the decoder checks the frame header CRC to confirm it synchronised correctly. Frame headers also carry the sample rate, bit depth and channel count, so decoding can begin even without a STREAMINFO block.
Inside a frame, the audio is not channel-interleaved. The RFC says each channel's subframe is stored one after another, which reduces decoder complexity at the cost of larger decode buffers. That differs from raw PCM, which interleaves channels sample by sample, and from the MD5 above, which is computed on the interleaved form.
The RFC also defines a streamable subset, meant to guarantee that a decoder that cannot seek can pick up in the middle of a stream, and to make hardware decoders more practical. Its limits include:
- Frame headers must describe the sample rate and bit depth themselves, without referring to STREAMINFO.
- No block may hold more than 16,384 interchannel samples, and audio at 48,000 Hz or below may not use blocks larger than 4,608 samples.
- Linear predictors for audio at 48,000 Hz or below must have an order of 12 or less.
- The Rice partition order must be 8 or less.
Finally, the RFC defines how FLAC is carried in other containers, with separate mappings for Ogg, Matroska and MP4 [Section 10].
Working With FLAC and PCM Day to Day
FLAC is best thought of as PCM in a compressed wrapper with built-in error checking. If you have raw PCM, you can encode it with FFmpeg by giving the raw format, sample rate and channel count before the input, as shown in our FFmpeg and raw PCM guide. If you are choosing between formats, our format comparison puts FLAC next to MP3, WAV and OGG. For the streaming side of lossless audio, see our article on what lossless really means.
Summary
RFC 9639 published FLAC as a Standards Track RFC with Proposed Standard status. It describes a lossless way to store integer PCM with 1 to 8 channels, 4 to 32 bits and sample rates up to 1,048,575 Hz, using blocking, optional stereo decorrelation, prediction and Rice-coded residuals. Its STREAMINFO block records the format in 34 bytes and stores an MD5 checksum of the interleaved little-endian PCM, which is what lets a decoder verify that every sample came back unchanged.
Sources and verification
The facts in this article were checked against the primary sources below on . Figures described as our own calculation are derived from those sources. If you spot a mistake, please tell us through the contact page.
- RFC 9639: Free Lossless Audio Codec (FLAC), December 2024 — every format fact in this article, with section numbers given in brackets in the text
- RFC Editor information page for RFC 9639 — the Proposed Standard status of the document