What gapless playback is, and why it keeps breaking
Gapless is a property of a whole chain, not a checkbox on a file format. Measured here — the same AAC bitstream that round-trips exactly in one container arrives 61.95 ms longer in another.
Gapless playback is a property of the whole chain from file to speaker, not a checkbox on a file format. Four things have to be true at once: the file records its own true length, the decoder honours that length, the player has the next track decoded and buffered before the current one ends, and the audio output stays open across the boundary. Break any one and you hear the same thing — a hiccup between tracks that were mastered to join.
Most of the silence involved was put there deliberately. Block-based encoders add samples at the start and the end of a stream because their transforms require it, and they record how many they added so a decoder can throw them away again. Here is what that costs when the record does not survive: the same AAC bitstream, from the same encoder, measured below, comes back 220,500 sample frames in one container and 223,232 in another. The difference is 61.95 ms of near-silence per track boundary, and the codec is not the variable.
Where the extra silence comes from
Hydrogenaudio’s account is the clearest primary description of the mechanism, and it names two causes rather than one: “compression scheme artifacts and poorly designed playback systems”. Both are real, they are independent, and they produce an identical symptom.

On the encoding side, the vocabulary is worth fixing precisely, because almost everything written about this topic uses the words loosely. “Silence at the beginning is called delay and silence at the end is padding.” Three separate mechanisms create them:
- The transform needs a run-up. Most lossy schemes use an overlapping transform — an MDCT — and an overlapping transform “unavoidably introduces a certain amount of silence… at the beginning of the stream”. The decoder’s inverse transform can add a little of its own on the way out.
- The overlap needs material at both ends. Because each encoded segment “depends in part on adjacent segments”, the encoder needs extra signal beyond the real start and end to encode the genuine edges accurately, so it supplies silence.
- The last block has to be filled. Transforms work on fixed-size blocks, so “in order to fill up the last block, silence may be appended to the input” — which makes the total amount of padding depend on the length of the track.
LAME’s own technical FAQ shows the arithmetic in the MP3 case: “For MPEG1, frame_size = 1152 samples/frame”, the MDCT overlap means “the last 288 samples of that granule will not be decoded. So LAME appends 288 samples of padding to the input file”, and if “the number of samples is not an exact multiple of 1152, then last frame of data is padded with 0’s”. It also notes that “ISO based encoders… introduce their own 528 sample delay”, so “a .wav file encoded & decoded will have a 1056 sample delay”.
The delay is not a universal constant — it is a property of the encoder that made the file. Hydrogenaudio publishes the common values:
| Encoder | Documented encoder delay |
|---|---|
| LAME | 576 samples |
| iTunes / QuickTime MP3 | 528 samples |
| Windows Media Player / FhG FastEnc | 672 samples |
At 44.1 kHz, 576 samples is 13.1 ms. That alone is barely perceptible. The audible gap is that plus the padding at the end of the previous track, plus whatever the player adds — which is why this is a chain problem.
The measurement: same audio, two containers, 61.95 ms apart
A five-second stereo WAV — exactly 220,500 sample frames at 44.1 kHz, constant
amplitude, no fades, so it begins and ends at full level the way a track
meant to segue does — was encoded three ways with afconvert on macOS and
decoded straight back. Run 2026-08-26.
One source, three encodes, one variable
-
ALAC in .m4a · lossless
220,500 frames back out
declared: 220500 valid + 0 priming + 684 remainder
Bit-identical to the source PCM. Note the 684 remainder frames: a lossless codec pads its final block too — 220,500 is not a multiple of ALAC’s 4,096-frame packet. It is never heard, because the true sample count travels with the audio.
-
AAC 192 kbit/s in .m4a
220,500 frames back out
declared: 220500 valid + 2112 priming + 620 remainder
Exact length restored. The container declared 2,112 frames of priming and 620 of remainder, and the decoder trimmed both. Lossy, gapless, no gap.
-
AAC 192 kbit/s as raw .aac
223,232 frames back out — 2,732 too many
+47.89 ms at the head, +14.06 ms at the tail = 61.95 ms
The same encoder, the same bitrate, the same audio. The raw stream carries no place to record the priming and remainder, so the decoder delivered them as audio.
Two details worth stating precisely, because the loose versions of both are everywhere.
The added region is near-silence, not silence. The leading 2,112 frames of the raw decode peak at a sample value of 175 against a source that peaks at 18,000 — roughly −40 dB. That is encoder filter ringing, and Hydrogenaudio warns about it directly when it notes that silent samples “may not strictly equal zero (due to the encoder filter ringing)”. It is why automatic silence-trimming plug-ins are unreliable: the thing they are looking for is not quite silent, and some music genuinely is.
Lossless formats pad as well; they simply always declare it. The ALAC row is the demonstration — 684 frames of remainder, 15.51 ms, invisible because the decoder was told the true length. FLAC does the same job through STREAMINFO, which records the total number of samples in the stream. So the accurate version of “lossless is inherently gapless” is: a lossless file will not make you guess where the audio ends. That is the whole of its advantage here, and it is a large one — and it is a different advantage from the one lossless compression is usually bought for, which is that the samples come back unchanged.
None of this is a reason to prefer one container over another for general use. Which format to keep a collection in turns on compatibility, tooling and size; gapless behaviour is one input among several, and for lossless collections it is not the deciding one.
Why MP3 is the awkward one, and why “MP3 cannot be gapless” is too crude
The problem with MP3 is not the codec. It is that the MPEG standard “defines no way to record the amount of delay or padding for later removal”, and encoder delay “may vary from encoder to encoder, making automatic removal difficult”. Compare that with the formats designed after the problem was understood: Ogg Opus puts a pre-skip field in its ID header, defined by RFC 7845 as “the number of samples (at 48 kHz) to discard from the decoder output when starting playback”, and signals the exact end through the final page’s granule position. The information has a defined home.
MP3’s answer was a convention rather than a standard. LAME writes the values into its own header — “LAME embeds the amount of padding in the ancillary data of the first frame of the MP3 file. (LAME INFO tag). The LAME decoder will use this information to remove the leading padding” — and Hydrogenaudio describes the situation exactly: “Some encoders use a nonstandard header to store actual encoder delay & padding values, but not all players/decoders support it.”
So the honest statement is a conditional rather than a prohibition. A LAME-encoded MP3 played by a player that reads the LAME header is gapless. The same file played by a player that ignores the header is not. Two identical files, two different results, decided by software you did not choose when you encoded them.
The four links, and why they all look the same
This is the diagnostic structure, and it is the thing the vendor FAQs leave out. Hydrogenaudio states the conditions for optimal gapless as a set of four that must all hold: the compression method supports it, the software “properly decodes the audio data and metadata”, “the next track is buffered and ready to play”, and “the output stream remains open between tracks”.
Four links, four causes, one symptom
Works when The format has a defined field for it — FLAC’s sample count, Opus’s pre-skip and final granule position, MP4’s priming and remainder — or the encoder wrote a LAME header.
Fails when The stream is raw, or the header was stripped by a tag editor, or a file was re-encoded from a source that already had the silence baked in.
Fix Re-rip or re-encode from the original. Editing this after the fact is fiddly manual work.
Works when The decoder reads the delay and padding and trims them, which is exactly what happened in row two of the measurement above.
Fails when It ignores a non-standard header, or hands the player everything it decoded including the padding.
Fix A different player, or a format whose length information is standard rather than conventional.
Works when The next file is opened, decoded and buffered while the current one is still playing.
Fails when The player waits for the end, then locates the file, opens it, decodes the first blocks and fills a buffer — a pause Hydrogenaudio puts at "as much as half a second, or even more".
Fix Nothing you can do to the files. This one is entirely the software.
Works when One continuous output stream carries both tracks, with no teardown in between.
Fails when The software "closes and re-opens the output stream when switching tracks, causing the hardware to create a very short click" — or, on a network, when each track is a separate remote load.
Fix Also entirely the software. This is the link that casting breaks even when links one to three are perfect.
The chain view also explains a boundary worth drawing explicitly: CD pregaps are a different subject. Hydrogenaudio is blunt that gapless playback “is not related to ‘gaps’ or ‘pregaps’ on CDs, at least not directly” — those are index-00 regions flagged on the disc, and stripping them with a ripper is not a route to gapless audio. On a properly mastered commercial CD it is “more likely to just create audible seams where there were none before.”
Why casting reintroduces the gap
You can have all four links right locally and still hear a seam the moment the audio leaves the machine, and the reason is structural rather than a fault in any device.
In a Google Cast media session the sender does not stream audio: it hands the receiver a URL and a MIME type, and the receiver fetches and decodes the media itself. A load request delivers one media resource. So when a track ends, whatever holds the queue has to notice and issue another load request, and the receiver has to fetch and buffer the next file from cold. That is link four failing across a network — the session boundary is the teardown.
The fix is the same idea as local buffering, applied remotely: the next track has to be queued on the device before the current one finishes. How a Cast session is actually structured is the longer version of why one load request is the unit, and the same question — is the next thing ready before this one ends — is what the whole path from file to speaker turns on at every stage.

Where Digr is, precisely
Digr is not gapless today. Not locally, and not over Google Cast. An article about gapless published by a player that is not gapless has to say so first.
Locally, playback is handed to the system media stack through Tauri’s asset protocol — no bytes pass through JavaScript and nothing is converted on the way, which is why it is dependable, and it is also why a live album has a seam between tracks. Digr does not own the decode and mixing path, so it does not own link three or link four.
Over Cast, the reason is the one above: a Cast receiver is handed one track at a time, which is why there is a pause between them. Digr keeps the queue while casting — the local engine is silenced but still owns queue, shuffle and repeat — but the receiver only ever holds the current media resource.
Both are named roadmap items, both in Digr Free, and neither has a date:
- Continuous Cast — the next track queued on the receiver before the current one ends — sits in the three-to-six-month block, alongside “gapless playback on smart speakers where the receiver supports it”. That qualification is the roadmap’s own, and it is honest: pre-loading is the sender’s half of the problem, and the device has to do its half.
- Truly gapless local playback is part of the longer-term audio-engine work — a Digr-side decode and mixing path, which is the only thing that can fix links three and four properly. Optional crossfade is a separate item on the same list, and deliberately so: it is a different feature, not a cheaper version of this one.
What works today is the shorter list, and gapless is not on it.
The short version
- Gapless is a chain property: the file’s declared length, the decoder’s respect for it, the player’s buffering, and an output stream that stays open. All four, or none.
- Encoders add silence on purpose — delay at the front, padding at the back — because overlapping block transforms need it, and they record how much.
- Measured here: the same AAC bitstream came back 220,500 frames in an MP4 and 223,232 as a raw stream — 61.95 ms of difference, from the container alone.
- “MP3 cannot be gapless” is too crude. MPEG defines no field for it; LAME writes one anyway; players that read it play LAME MP3s gaplessly.
- “Lossless is inherently gapless” is nearly right. ALAC still padded its final block by 684 frames — it just always declares the true length.
- A perfect file can still gap, because links three and four live in the player.
- Casting breaks link four structurally, because a Cast receiver is handed one track at a time.
- Digr is not gapless today; local gapless and Continuous Cast are both planned Free work with no dates.
Sources
- Hydrogenaudio — Gapless playback — the two causes, “compression scheme artifacts and poorly designed playback systems”; “Silence at the beginning is called delay and silence at the end is padding”; the MDCT and block-filling explanations; “The popular MP3 standard, for example, defines no way to record the amount of delay or padding for later removal”; “Some encoders use a nonstandard header to store actual encoder delay & padding values, but not all players/decoders support it”; the four conditions for optimal gapless including “the output stream remains open between tracks”; the encoder-delay table (LAME 576, iTunes/QuickTime 528, WMP/FhG FastEnc 672); the half-a-second buffering pause; the warning that silent samples “may not strictly equal zero (due to the encoder filter ringing)”; and that gapless “is not related to ‘gaps’ or ‘pregaps’ on CDs”
- LAME technical FAQ — “For MPEG1, frame_size = 1152 samples/frame”; “the last 288 samples of that granule will not be decoded. So LAME appends 288 samples of padding to the input file”; padding “with 0’s” when the sample count is not a multiple of 1152; “ISO based encoders… introduce their own 528 sample delay. A .wav file encoded & decoded will have a 1056 sample delay”; and “LAME embeds the amount of padding in the ancillary data of the first frame of the MP3 file. (LAME INFO tag). The LAME decoder will use this information to remove the leading padding”
- RFC 7845 — Ogg Encapsulation for the Opus Audio Codec — pre-skip as “the number of samples (at 48 kHz) to discard from the decoder output when starting playback”, the latency “introduced during the decoding process, to allow for overlap in the CELT mode, stereo mixing in the SILK mode, and resampling”, and end trimming through the final page’s granule position
- RFC 9639 — Free Lossless Audio Codec (FLAC) — STREAMINFO carrying the total number of interchannel samples, which is what lets a FLAC decoder know exactly where the audio ends
- Google Cast — Overview — the receiver as the component “responsible for responding to Sender commands and for conveying streaming content”, which is why a media session delivers one resource at a time and a queue advances by another load request
- Digr — features and roadmap — local playback handed to the system media stack and the seam that follows from it; Continuous Cast and “gapless playback on smart speakers where the receiver supports it” as planned Free work at three to six months; truly gapless local playback and optional crossfade as planned Free work in the longer-term audio-engine initiative
- The measurement in this article was run on 2026-08-26 on macOS using
afconvert,afinfoand Python’s standard library, on a five-second deterministic test signal generated for the purpose. Frame counts are as reported byafinfoor counted from the decoded files; every millisecond figure is that count divided by 44,100. No MP3 encoder was involved, because none ships with macOS — every MP3 number above is quoted from the two sources named, not measured here. No listening test was performed and none is claimed: Hydrogenaudio warns that generated pure tones are a poor way to evaluate gapless by ear, so this measurement counts samples instead. No player was instrumented, and no player is described here as gapless or not gapless
Common questions
What is gapless playback?
Gapless playback means consecutive tracks join with no added silence and no interruption, so an album mastered as one continuous piece of music plays as one continuous piece of music. It requires four things at once: a file that records its own true length, a decoder that honours that length, a player that has the next track ready before the current one ends, and an output stream that is not closed and reopened between the two. Any one of the four failing produces the same audible symptom.
Can MP3 be gapless?
Yes, in practice, although the MPEG standard itself provides no place to record how much silence an encoder added. LAME writes the encoder delay and padding into a non-standard header anyway, and a player that reads that header can trim them and play the file gaplessly. So the accurate statement is not that MP3 cannot be gapless — it is that gapless MP3 depends on a convention outside the standard, which some players implement and others do not.
Is FLAC automatically gapless?
A FLAC file will not add silence you have to remove, because the stream records exactly how many samples it contains, so a decoder always knows where the audio really ends. That solves the file half of the problem and not the playback half. A player that closes and reopens its audio output between tracks, or that starts reading the next file only once the current one has finished, will produce an audible gap between two flawless FLAC files.
Why does my live album have gaps when the files are fine?
Because file continuity and playback continuity are different things. If the files record their true length correctly, the remaining suspects are all in the player: it may be closing the audio output at each track boundary, which produces a click or a short silence, or it may not begin loading and decoding the next track until the current one ends, which produces a pause of anything up to half a second. Neither is fixable by re-encoding the files.
Is gapless playback the same as crossfade?
No, and they are close to opposites. Gapless removes silence that should not be there so the tracks meet exactly as they were mastered. Crossfade deliberately overlaps the end of one track with the start of the next, altering both. Crossfade will hide a gap, which is why it is sometimes suggested as a fix, but on an album that already segues it destroys the transition the artist built — and on a loud continuous mix it introduces a volume dip where there was none.
Is Digr gapless?
Not today, locally or over Google Cast, and both are named roadmap items rather than shipping behaviour. Digr hands local playback to the system media stack, which is why it is dependable and why a live album has a seam between tracks. Truly gapless local playback is planned Digr Free work in the longer-term horizon, and Continuous Cast — the next track queued on the receiver before the current one ends — is planned Digr Free work at the three-to-six-month horizon. Neither has a date.
- gapless
- encoder delay
- padding
- priming
- AAC
- MP3
- LAME
- FLAC
- Opus
- Google Cast