[mad-dev] ancillary bits

Rob Leslie rob@mars.org
Sat, 19 Jul 2003 19:09:51 -0700

On Saturday, July 19, 2003, at 05:42  PM, Russell O'Connor wrote:
> Okay I've been testing using this, and in my test file that I have the 
> first 4 bytes read by the ancillary pointer are 'n' 'g' 0x00 0x00, so 
> I suspect that the pointer is off by 2 bytes.  Not seeing what was 
> wrong I tried a different file, this time the bytes were 'X' 'i' 'n' 
> 'g' which is great.  So I supsect that my original test file is > broken.

It does appear that way...

> I don't suppose anyone here can check this for me and/or teach me how 
> to read an MP3 header so that I can find where the ancillary data is.

Unfortunately reading the frame header is not sufficient to determine 
where the ancillary data is. The entire main_data of the frame must be 
processed in order to know where it ends, as that is where the 
ancillary data begins.

There is however a general rule that may be helpful: in the case of 
2-channel (stereo) 44100 Hz streams, there always follows 32 bytes of 
side information after the frame header (or CRC). If all of those bytes 
are zero, the frame is silent and there will not be any further data in 
the frame. Therefore the ancillary data begins immediately after these 
32 bytes of side information (unless the following frame's main_data 
begins there instead.) I mention this because Xing VBR headers are 
typically added to frames of silent audio.

> Here is the relevent part of my first possibly broken test MP3 file, 
> after the ID3v2 header.  You can see the first frame begins at 10f4.
> 00010f0: 0000 0000 fffa 9064 861f 0000 0000 0000  .......d........
> 0001100: 0000 0000 0000 0000 0000 0000 0000 0000  ................
> 0001110: 0000 0000 0000 0000 5869 6e67 0000 000f  ........Xing....
> 0001120: 0000 1bbd 003c f125 0003 0608 0a0e 1012  .....<.%........
> 0001130: 1417 1a1c 1f21 2327 292b 2d2f 3335 3739  .....!#')+-/3579
> 0001140: 3d3f 4143 4549 4b4e 5052 5658 5a5d 5f63  =?ACEIKNPRVXZ]_c
> 0001150: 6568 6a6d 7072 7477 7a7c 7e80 8386 888b  ehjmprtwz|~.....
> 0001160: 8d8f 9295 9799 9d9f a1a3 a6a9 acae b1b3  ................
> 0001170: b7ba bcbe c1c4 c6c9 cbcf d1d4 d6d8 dcde  ................
> 0001180: e1e3 e5e9 ebed f0f2 f6f8 fafd 0000 004e  ...............N
> 0001190: 4c41 4d45 332e 3931 2003 be00 0000 0000  LAME3.91 .......

I suspect the problem with this test file is that the frame has CRC 
protection enabled (bit 0 of 0xfffa is clear). It therefore has an 
extra 2-byte CRC (0x861f) after the frame header and before the frame's 
main_data. Whatever software wrote this Xing header (LAME?) may not 
have taken this into account, and wrote the header 2 bytes earlier than 
it should have -- the 'X' and 'i' bytes of the header in fact clobber 
the last two bytes of the frame's side information.

Rob Leslie