BWF and iXML metadata explained: what lives inside a broadcast WAV
Every professional sound roll is a WAV file carrying two hidden payloads: a bext chunk with a sample-accurate start time, and an iXML chunk with the scene, take, track names and frame rate that make dailies label themselves. Here is what each field means, how the time reference converts to timecode with real numbers, and which of it your NLE actually reads.
BWF is just WAV, plus discipline
A WAV file is a container of chunks: a fmt chunk describing the audio, a data chunk holding the samples, and any number of optional chunks that software is free to ignore. Broadcast Wave Format (BWF), defined by the EBU in Tech 3285, adds exactly one mandatory chunk to plain WAV: bext, the broadcast extension. That is the whole trick — a BWF plays anywhere a WAV plays, because to anything that does not understand bext, it is a WAV.
Field recorders write a second, unofficial-but-universal chunk alongside it: iXML, an XML document embedded in the file, specified by an industry consortium rather than a standards body. In practice the two divide the work: bext answers “when did this file start”, iXML answers “what is it” — scene, take, roll, track names, and the frame-rate context bext famously lacks.
The bext chunk, field by field
The bext chunk is a fixed-layout binary structure. The fields that matter on a shoot:
- Description (256 characters) — free text. Recorders typically write something like
sSPEED=025.000-ND sTAKE=012 sSCENE=14A sTAPE=SR003— a flattened copy of the slate info, useful when iXML is missing. - Originator (32) and OriginatorReference (32) — the recorder model and a machine-generated unique reference for the file.
- OriginationDate (
yyyy-mm-dd) and OriginationTime (hh:mm:ss) — wall-clock creation stamp, seconds precision only. Do not sync from these; that is not their job. - TimeReference (64-bit integer) — the field everything hangs on: the number of samples elapsed since midnight at the moment the first sample was recorded. More below.
- Version, UMID — version 1 added a 64-byte SMPTE unique material identifier; most workflows never touch it.
- Loudness fields (version 2) — integrated loudness, loudness range, max true peak and friends, added for EBU R128 delivery masters. Field recorders leave them empty; they matter when the BWF is a broadcast deliverable, not a rush.
- CodingHistory — free-text log of the signal chain (
A=PCM,F=48000,W=24…), appended by each processing stage in a well-behaved pipeline.
TimeReference: one integer, sample-accurate
The time reference is deliberately simple: samples since midnight. Divide by the sample rate and you have the start time of day; convert that to a frame count and you have the start timecode. One worked example, at 48 kHz and 25 fps:
- A recorder rolls at timecode
10:35:20:12. Seconds since midnight: 10×3600 + 35×60 + 20 = 38,120 s. - In samples: 38,120 × 48,000 = 1,829,760,000. The 12 frames add 12 × (48,000 ÷ 25) = 12 × 1,920 = 23,040.
- TimeReference = 1,829,783,040. Reading it back is the same arithmetic in reverse.
Two properties fall out of this design. First, it is sample-precise: the recorder knows its start to 1/48,000 of a second, while a camera’s timecode is only frame-precise — which is why, in a dual-system sync, the residual error belongs to the camera side. Second, it is context-dependent: the integer is meaningless until you know the sample rate it counts in, and — for display as timecode — the frame rate to divide it by. And here is the catch:
The bext chunk stores neither a frame rate nor a drop-frame flag. The sample rate at least lives next door in fmt , but the frame rate is simply absent from the standard. A tool that shows you 10:35:20:12 from a bare BWF has assumed a frame rate — and at 23.976 or 29.97 drop-frame, assumptions are how sound rolls end up minutes wrong by wrap. Fixing that gap is half the reason iXML exists.
iXML: the slate, machine-readable
iXML is a plain XML document stored in its own chunk. Because it is XML, it is extensible and human-readable — you can open a sound roll in a hex viewer and literally read the scene number. The sections a post workflow leans on:
- PROJECT, SCENE, TAKE, TAPE — the slate.
TAPEis the sound-roll name (SR003), the audio-side equivalent of a camera reel: the identity that follows the material through ALE files and conform all the way to the finish. - CIRCLED, NO_GOOD, WILD_TRACK, NOTE — the sound mixer’s verdicts. Circled takes are the ones the script supervisor marked as keepers; a dailies tool that surfaces them is doing the assistant editor’s triage for free.
- SPEED — the section that completes
bext. It statesFILE_SAMPLE_RATE,AUDIO_BIT_DEPTH, and cruciallyTIMECODE_RATEas an exact ratio —25/1,24/1,30000/1001— plusTIMECODE_FLAGfor drop/non-drop. Fractional rates that bext cannot express are stated exactly. It also repeats the timestamp asTIMESTAMP_SAMPLES_SINCE_MIDNIGHT_HI/LO, so a file whose bext was damaged can still be placed. - TRACK_LIST — one entry per track with channel index and
NAME: Boom, Lav 1, Lav 2, Mix L. This is where your editor’s track labels come from — or fail to. - FILE_SET and FAMILY_UID — recorders can write one polyphonic WAV (all tracks interleaved in a single file) or a set of monophonic files, one per track. For mono sets, every file carries the same
FAMILY_UIDand its index in the set, so software can reassemble the take without guessing from filenames. - HISTORY and FILE_UID — the original filename and a unique ID that survive renaming. When a rushes folder has been “helpfully” renamed by hand, these are how the sound report still matches the files.
What your NLE actually reads
Support is real but uneven, and knowing the gaps saves an afternoon:
- DaVinci Resolve reads the bext time reference as start timecode and pulls scene, take and track names from iXML into the metadata panel — the audio side of its timecode-based multicam sync.
- Premiere Pro reads the time reference for clip start TC and displays iXML track names on import; scene and take are visible in metadata but are not used to name anything automatically.
- Avid Media Composer reads bext TC on link, but the full slate traditionally arrives via an ALE generated from exactly these fields — the iXML-to-bin bridge every dailies tool builds.
The common denominator: the time reference is read nearly everywhere; the descriptive metadata survives only if your ingest path deliberately carries it forward.
How good metadata dies
BWF metadata is robust in the file and fragile in the pipeline. The usual killers:
- Re-export. Bounce a WAV out of a DAW or convert it with a casual utility, and both chunks are typically gone — the new file is audio that sounds identical and knows nothing. Any processing step (level rides, denoise) must copy chunks forward explicitly.
- Lossy transcodes. An MP3 or AAC has no bext and no iXML, full stop. The moment someone “sends the audio over” as an MP3, the sync workflow is back to waveform matching.
- Sample-rate assumptions. Productions recording at 48.048 kHz for pull-down workflows carry a time reference counted at that rate. Interpret it at 48,000 and every derived timecode is 0.1% off — a “drift” that was actually arithmetic.
- Midnight. Samples since midnight means a shoot rolling past 00:00 wraps to small numbers. Files sort wrong and TC-based pairing crosses days; the origination date field is the tiebreaker.
- The 4 GB cliff. WAV’s 32-bit size field caps files at 4 GB — about 100 minutes of eight-track 48 kHz/24-bit. Long multitrack rolls switch to RF64/BW64, the 64-bit successors that keep bext and iXML intact; older software that chokes on them is choking on the container, not the metadata.
Where Launchr Post fits
Launchr Post reads all of the above during ingest, on your own machine. The bext time reference — interpreted through the iXML SPEED section’s exact rates, not an assumption — drives timecode-first sync against the camera files; scene, take, tape and track names flow into the clip naming, the transcripts and the editor package; circled takes stay marked. When a file arrives stripped of its metadata, the sync falls back to LTC or waveform matching and the per-clip report says so — so you know which files carried their own identity and which were rescued.
See what your sound rolls know
Drop a shoot day into Launchr Post and inspect the decoded bext and iXML fields per file. It syncs, sorts and transcribes — then hands your editor the whole package.