Chunk sizes in a WAV file are 32-bit, so a file stops at 4 GB: a little over 4 hours of
stereo audio at 48 kHz and 24 bits, and much less for a multichannel programme. BW64
keeps the WAV layout and puts the sizes that do not fit in a ds64 chunk,
straight after the header. The chunk is RF64’s, from EBU Tech 3306; the field names
below are those of libbw64, the EBU’s reference library, with Tech 3306’s names beside
them.
Fields
The chunk’s data is 28 bytes plus 12 for each table entry. Offsets are from the start of the chunk’s data, after its eight-byte header; in a file the data starts at offset 20. Numbers are little-endian.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 8 | u64 | bw64Size (riffSize) | the real size of the outer chunk: the file size minus 8 |
| 8 | 8 | u64 | dataSize | the real size of the data chunk |
| 16 | 8 | u64 | dummySize (sampleCount) | in Tech 3306 the real frame count, for a fact chunk whose own count is 0xFFFFFFFF; libbw64 always writes 0 |
| 24 | 4 | u32 | tableLength | the number of table entries that follow |
| 28 | 12 each | record | table | sizes of other chunks too big for 32 bits, below |
Since libbw64 writes 0 in the third field, a reader should not depend on it for the length of the audio: for PCM the frame count is the data size divided by the block align.
The size rule
Any 32-bit size in the file can be 0xFFFFFFFF, which means “look in
ds64”. libbw64 resolves it this way (its getChunkSize64), and
the explorer does the same:
- the outer size at offset 4 takes
bw64Size; - the data chunk’s size takes
dataSize; - any other chunk’s size takes the table entry with the same ID;
- a
factchunk’s count of0xFFFFFFFFtakes the third field.
A size that is not 0xFFFFFFFF is read as it is. The data chunk of a small
file may carry its real 32-bit size; the explorer then uses it, and reports it when
dataSize disagrees. A size of 0xFFFFFFFF for which
ds64 gives nothing, with no table entry for that ID, is taken to run to the
end of the file, and reported.
The table
Each entry gives the size of one more chunk that does not fit in 32 bits:
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 4 | char[4] | chunkId | the chunk’s ID |
| 4 | 8 | u64 | chunkSize | its real size |
The table is usually empty. The explorer reports a tableLength larger than
the chunk can hold.
An example
The start of a BW64 file holding 5,000,000,000 bytes of 16-bit stereo audio, built for this page:
00000000 42 57 36 34 FF FF FF FF 57 41 56 45 64 73 36 34 BW64....WAVEds64
00000010 1C 00 00 00 48 F2 05 2A 01 00 00 00 00 F2 05 2A ....H..*.......*
00000020 01 00 00 00 80 7C 81 4A 00 00 00 00 00 00 00 00 .....|.J........
| Offset | Bytes | Value |
|---|---|---|
| 4 | FF FF FF FF | the outer size: look in ds64 |
| 16 | 1C 00 00 00 | the chunk’s size, 28 |
| 20 | 48 F2 05 2A 01 00 00 00 | bw64Size, 5,000,000,072 |
| 28 | 00 F2 05 2A 01 00 00 00 | dataSize, 5,000,000,000 |
| 36 | 80 7C 81 4A 00 00 00 00 | 1,250,000,000 frames, as Tech 3306 would give it; a file written by libbw64 has zeros here |
| 44 | 00 00 00 00 | tableLength, 0 |
The format chunk follows at offset 48, then a data chunk whose size reads
FF FF FF FF. The outer size counts 4 bytes of WAVE, 36 of
ds64, 24 of format chunk, the data chunk’s 8-byte header and the
5,000,000,000 bytes of samples.