I see that the algorithm for 32 bit output in madplay quantizes to 24 bit; I'm a little daft when it comes to fixed point representations, but why are some of the fractional bits discarded even when you're outputting in full 32 bit?
There's also one more thing I don't understand; the original sign bit of the fixed point number isn't kept (as far as I can see), instead the least significant whole part bit occupies the sign position. Does this whole part bit represent the sign (a little confused here)?
Regards
Arve Knudsen
On Thursday, July 3, 2003, at 04:26 AM, Arve Knudsen wrote:
I see that the algorithm for 32 bit output in madplay quantizes to 24 bit; I'm a little daft when it comes to fixed point representations, but why are some of the fractional bits discarded even when you're outputting in full 32 bit?
This is mostly the result of convenience of uniformity. I think some of the 32-bit audio hardware out there ignores the least significant byte, so it seemed appropriate to round/dither to the 24th bit -- not that the bits past the 24th are terribly important or accurate anyway.
There's nothing wrong with using all available bits for 32-bit output.
There's also one more thing I don't understand; the original sign bit of the fixed point number isn't kept (as far as I can see), instead the least significant whole part bit occupies the sign position. Does this whole part bit represent the sign (a little confused here)?
In two's complement notation, the least significant whole part bit (and all intervening bits) are guaranteed to be the same as the sign bit when the absolute value is less than MAD_F_ONE. Since clipping ensures this condition, shifting will not affect the sign of the value.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
[To: mad-dev@lists.mars.org]
I want to incorporate xing.c into my project, so I was wondering if somone can explain that the ancillary bits pointer is?
Also, when is it valid to use it, after mad-decode-header? or must I do mad-decode.
- -- Russell O'Connor http://math.berkeley.edu/~roconnor/ Work to ensure that Iraq is run by Iraqis.
On Sunday, July 13, 2003, at 10:12 PM, Russell O'Connor wrote:
I want to incorporate xing.c into my project, so I was wondering if somone can explain that the ancillary bits pointer is?
"Ancillary data" is the data in an MPEG audio stream between the end of one frame and the beginning of the next. After a successful call to mad_frame_decode(), a pointer to this data is placed in stream->anc_ptr and the length in stream->anc_bitlen.
Since the data is neither necessarily byte-aligned nor an integral number of bytes, MAD uses a "bit pointer" structure that can be passed to mad_bit_read() to read the data as arbitrary-sized bit string words.
It happens that Xing VBR header information is stored in the ancillary data of the first frame of a VBR stream, so that's why the bit pointer is used.
Also, when is it valid to use it, after mad-decode-header? or must I do mad-decode.
The location and size of the ancillary data is not known until after the frame is fully decoded, so it's not sufficient to merely decode the header; you must decode the entire frame.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
[To: mad-dev@lists.mars.org]
On Sun, 13 Jul 2003, Rob Leslie wrote:
"Ancillary data" is the data in an MPEG audio stream between the end of one frame and the beginning of the next. After a successful call to mad_frame_decode(), a pointer to this data is placed in stream->anc_ptr and the length in stream->anc_bitlen.
It happens that Xing VBR header information is stored in the ancillary data of the first frame of a VBR stream, so that's why the bit pointer is used.
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.
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. 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 .......
Thanks for anyone who can help.
- -- Russell O'Connor http://math.berkeley.edu/~roconnor/ Work to ensure that Iraq is run by Iraqis.
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.