FLAC
How musefs scans and synthesizes native FLAC files (.flac). FLAC inside an
Ogg container is a different beast — see Ogg. For the segment
model these layouts plug into, see
the segment model.
What round-trips
- All text tags. Canonical keys (
title,artist,albumartist,date,tracknumber, …) map to their conventional Vorbis field names via the shared vocabulary (musefs-format/src/tagmap.rs); any other field round-trips verbatim by its own name. Multi-value fields keep their order. User-defined keys that are not legal Vorbis field names (empty, containing=, control characters, or non-ASCII bytes — i.e. outside ASCII0x20–0x7Dminus=) are dropped on synthesis and logged; they cannot round-trip by name. - Binary metadata blocks.
APPLICATIONandCUESHEETblocks are captured at scan time as binary tags (anAPPLICATIONpayload includes its 4-byte application id) and re-emitted on synthesis, streamed from the DB rather than held in memory. - Embedded pictures. Each
PICTUREblock round-trips with its MIME type, picture type, description, and dimensions; image bytes are stored content-addressed and streamed at read time. - Structural blocks.
STREAMINFOandSEEKTABLEare preserved bit-exact. They are captured into the read-onlystructural_blocksstore at scan time (external tools must not edit them) and re-emitted on synthesis.
Lossy edges
PADDINGblocks are dropped — the synthesized file carries no padding.- Metadata blocks of unknown/reserved types are dropped at scan time.
- A
PICTUREblock whose picture type falls outside the standard0–20range is clamped to0(Other) at scan time, matching the store'strack_art.picture_typeCHECK. This sharedPICTUREparser also serves FLAC-in-Ogg, so the same clamp applies there. - The
VORBIS_COMMENTvendor string is replaced with musefs's own. - Vorbis field names are case-insensitive by spec; musefs re-emits canonical
keys under their conventional uppercase names and upper-cases unknown
field names. A field stored as
MixedCasecomes back asMIXEDCASE— same field to a conforming reader, different bytes.
How synthesis works
flac::synthesize_layout (musefs-format/src/flac.rs) builds the layout in
this order — an inline metadata region, DB-streamed payloads, then the
untouched audio:
offset 0
┌──────────────────────────────────────────────┐ ┐
│ █ "fLaC" marker (Inline) │ │
│ █ STREAMINFO / SEEKTABLE, bit-exact (Inline) │ │ generated
│ █ VORBIS_COMMENT rebuilt from DB (Inline) │ │ metadata
│ ▒ APPLICATION / CUESHEET bodies (BinaryTag) │ │ region
│ █ PICTURE framing + ▒ image bytes (ArtImage) │ │
├──────────────────────────────────────────────┤ ┘
│ ░ audio frames, verbatim (BackingAudio) │
└──────────────────────────────────────────────┘
EOF █ inline-generated ▒ DB-streamed ░ untouched backing
Inline— thefLaCmarker plus the preserved structural blocks (STREAMINFO,SEEKTABLE, sorted by block type) and aVORBIS_COMMENTblock regenerated entirely from the DB tag rows.BinaryTag— one segment per storedAPPLICATION/CUESHEETblock, streamed from the DB at read time.ArtImage— onePICTUREblock per linked art row; the block framing is inline, the image bytes stream from the blob store.BackingAudio— the original audio frames, served by positioned reads at the storedaudio_offset/audio_length.
Structural blocks normally come from the structural_blocks store. A
database scanned before that store existed has no rows there; synthesis then
falls back to re-reading the file's front for every preserved block
(carrying APPLICATION/CUESHEET inline and suppressing the streamed
binary tags so nothing is emitted twice). A re-scan upgrades the track to
the streamed path.
Quirks & invariants
- The audio frames are never touched: the backing segment starts exactly at
the scanned audio offset, and the byte-identical-audio property is asserted
by
musefs-format/tests/proptest_flac.rsand the mutagen interop suite (musefs-core/tests/interop_emit.rs). - Synthesis re-parses its own inline output in tests
(
flac_tag_roundtrip_is_stable): the regenerated front must be a valid FLAC metadata region whose computed audio boundary equals the layout's header length. - Block-body sizes are bounded at parse time (
MAX_BLOCK_BODY); a crafted file cannot force a huge allocation. - The parser now rejects (at scan and synthesis) any FLAC whose metadata does not begin with exactly one 34-byte STREAMINFO block; a crafted store providing malformed structural rows fails synthesis with a controlled error rather than emitting decoder-rejected output.