Hey @PG1 ,
this time no human research just a fast analyze of the produced files with an AI after I saw that TPOS was not handled correctly in latest release. I did not try in 13.0.20 to see if it’s a regression or not.
Summary
This is a follow-up to the trkn bug fixed in WaveLab Pro 13.0.30 (thanks!),
but it is a distinct bug in the same M4A tag writer. When a disc number
(ID3v2 “TPOS”-style field) is set in the metadata, WaveLab writes the
iTunes-style disc-number atom (moov.udta.meta.ilst.disk) with a perfectly
valid structure but all values zeroed (disc 0 of 0). Apple Music, iTunes,
Finder and every other player treat 0/0 as “not set”, so the disc number
field shows up empty. The track number (trkn) in the same files is now
correct — the 13.0.30 fix works.
Environment
- WaveLab Pro 13.0.30, macOS 26.5 (Apple Silicon)
- Render format: AAC (M4A) through the bundled FFmpeg
- Disc number set in the WaveLab metadata (TPOS field) 1/2; track numbers 1/11
and 2/11 from the montage
Steps to reproduce
- In WaveLab Pro, set up an M4A (AAC) render with a disc number in the
metadata (e.g. 1/2) and track numbers. - Render the file.
- Inspect the result:
ffprobe file.m4ashowsdisc: 0(and the correct
track: 1/11); Apple Music shows an empty disc number.
Expected result
The disc number is displayed (“1/2”); ffprobe shows disc: 1/2.
Actual result — the bytes
Hex dump of the disk atom as written by WaveLab 13.0.30 (identical in every
rendered file):
00 00 00 1E 64 69 73 6B disk atom, size 30 OK
00 00 00 16 64 61 74 61 data atom, size 22 OK
00 00 00 00 type 0 (binary) OK
00 00 00 00 locale OK
00 00 | 00 00 | 00 00 pad | disc=0 | total=0 WRONG — user's value lost
Unlike the 13.0.20 trkn bug, the structure is exactly the canonical
iTunes/AtomicParsley form (type 0, 6-byte payload of three big-endian
uint16). Only the values are wrong: the disc number entered by the user
never reaches the file. Rewriting just those two payload bytes (single-
variable experiment, verified with cmp -l) makes the disc number appear
correctly everywhere.
Possible root cause hint
In the same files, some text atoms (©day, ©ART, ©alb) are written with
a UTF-8 BOM (EF BB BF) prefixed to the value — which looks like the raw
content of internal ID3v2-style UTF-8 strings leaking through. TPOS is a
text frame (“1/2” in ID3v2); a whole-pattern numeric parse such as
sscanf(value, "%u/%u", &disc, &total) fails on the very first byte of a
BOM-prefixed string, fills neither variable, and leaves both at their
zero-initialized defaults — exactly the observed 0/0. (Note it has to be a
whole-pattern parse: atoi + manual ‘/’ split would yield 0/2 instead.)
An alternative explanation with the same on-disk result: the presence of
TPOS triggers emission of the disk atom (13.0.20 renders without TPOS have
no disk atom at all), but the value is dropped somewhere in the plumbing
and the writer emits its zero defaults. The track number, taken from the
montage’s automatic track numbering rather than a text field, is unaffected
either way. The BOM in the text atoms is itself a minor spec violation
worth fixing at the same time (well-known type 1 is UTF-8 without BOM);
it is invisible in players but breaks sorting/string matching. Also noted:
13.0.30 no longer writes a ©too atom.
Reference implementations
- AtomicParsley
src/main.cpp(Meta_disknumhandler): type 0 + three
uint16 (pad, disc, total) — byte-identical structure to WaveLab’s, with
real values. - FFmpeg
libavformat/movenc.c,mov_write_trkn_tag(..., disc=1): the
8-byte variant, also accepted by Apple Music. - Apple QuickTime File Format Specification, “Metadata” chapter, “Data
Atoms” / “Well-Known Types”.
Sample files (WaveLab render + byte-patched fixed copy) available on
request.
Thanks,
Raph