Identifying free format MP3s |
![]() ![]() |
Identifying free format MP3s |
May 22 2003, 17:50
Post
#1
|
|
![]() Group: Members Posts: 3621 Joined: 14-May 03 From: Bad Herrenalb Member No.: 6613 |
Hello!
I was wondering how to identify free format MP3 files. I am currently working on a Visual Basic ActiveX which should extract information about MP3/MP2/MP1 files and at the moment it recognizes a 640 kbps MP3 file totally wrong (MPEG 1 Layer I, 448 kbps, 48 KHz, 50/15 microsec. emphasis...). Thanks! -------------------- http://listening-tests.hydrogenaudio.org/sebastian/
|
|
|
|
May 22 2003, 19:31
Post
#2
|
|
![]() LAME developer Group: Developer Posts: 768 Joined: 22-September 01 Member No.: 5 |
http://www.mp3-tech.org/programmer/frame_header.html
the bitrate table index 0 indicates a free format stream |
|
|
|
May 22 2003, 19:45
Post
#3
|
|
![]() Group: Members Posts: 3621 Joined: 14-May 03 From: Bad Herrenalb Member No.: 6613 |
Yes, I know that. I also have that bitrate table implemented inside my program, but the MP3 analyzer returns bitrate index 14 (which in my case denotes MPEG 1 Layer I with 448 kbps). Also, it seems that the whole header is different, as the tool returns 48 KHz, 50/15 microsec. emphasis...
-------------------- http://listening-tests.hydrogenaudio.org/sebastian/
|
|
|
|
May 22 2003, 19:59
Post
#4
|
|
![]() LAME developer Group: Developer Posts: 768 Joined: 22-September 01 Member No.: 5 |
you may want to look if there is no ID3v2 tag in front of your stream.
|
|
|
|
May 22 2003, 20:09
Post
#5
|
|
![]() Group: Members Posts: 3621 Joined: 14-May 03 From: Bad Herrenalb Member No.: 6613 |
No there isn't, and even if a tag would be there, my program would read the first valid MPEG frame.
-------------------- http://listening-tests.hydrogenaudio.org/sebastian/
|
|
|
|
May 22 2003, 20:14
Post
#6
|
|
![]() Group: Members Posts: 3621 Joined: 14-May 03 From: Bad Herrenalb Member No.: 6613 |
Here is the portion of the code, which evaluates the MPEG header data (VB):
CODE Get intFileNumber, lngOffset, bytFourBytes
lngMPEGHeader = ByteArrayToLong(bytFourBytes) intMPEGSync = BitShiftRight(lngMPEGHeader, 21) And &H7FF bytMPEGVersionIndex = BitShiftRight(lngMPEGHeader, 19) And &H3 bytMPEGLayerIndex = BitShiftRight(lngMPEGHeader, 17) And &H3 bytMPEGCRC = BitShiftRight(lngMPEGHeader, 16) And &H1 bytMPEGBitRateIndex = BitShiftRight(lngMPEGHeader, 12) And &HF bytMPEGSamplingRateIndex = BitShiftRight(lngMPEGHeader, 10) And &H3 bytMPEGPadding = BitShiftRight(lngMPEGHeader, 9) And &H1 bytMPEGPrivate = BitShiftRight(lngMPEGHeader, 8) And &H1 bytMPEGChannelModeIndex = BitShiftRight(lngMPEGHeader, 6) And &H3 bytMPEGExtendedChannelModeIndex = BitShiftRight(lngMPEGHeader, 4) And &H3 bytMPEGCopyright = BitShiftRight(lngMPEGHeader, 3) And &H1 bytMPEGOriginal = BitShiftRight(lngMPEGHeader, 2) And &H1 bytMPEGEmphasisIndex = lngMPEGHeader And &H3 -------------------- http://listening-tests.hydrogenaudio.org/sebastian/
|
|
|
|
May 22 2003, 20:30
Post
#7
|
|
![]() Group: Members Posts: 3621 Joined: 14-May 03 From: Bad Herrenalb Member No.: 6613 |
Someone just sent me an email asking me to send that song, but I have deleted the mail by mistake.
Anyway, the file has over 20 MB (it is a 640 kbps file). -------------------- http://listening-tests.hydrogenaudio.org/sebastian/
|
|
|
|
May 22 2003, 20:33
Post
#8
|
|
![]() LAME developer Group: Developer Posts: 768 Joined: 22-September 01 Member No.: 5 |
yes, it was me. just send me the first 100 k bytes for testing.
This post has been edited by robert: May 22 2003, 21:50 |
|
|
|
May 22 2003, 20:45
Post
#9
|
|
![]() Group: Members Posts: 3621 Joined: 14-May 03 From: Bad Herrenalb Member No.: 6613 |
It's sent!
-------------------- http://listening-tests.hydrogenaudio.org/sebastian/
|
|
|
|
May 22 2003, 20:48
Post
#10
|
|
![]() LAME developer Group: Developer Posts: 768 Joined: 22-September 01 Member No.: 5 |
QUOTE (Sebastian Mares @ May 22 2003 - 09:09 PM) No there isn't, and even if a tag would be there, my program would read the first valid MPEG frame. well, maybe your stream has some sort of TAG infront and you synchronize not at the first mpeg header but at some point within the heading TAG. that would explain your results. |
|
|
|
May 22 2003, 20:53
Post
#11
|
|
![]() Group: Members Posts: 3621 Joined: 14-May 03 From: Bad Herrenalb Member No.: 6613 |
Actually, it has a LAME Info tag, but it is skipped somhow (it shouldn't). The first valid frame is detected at offset 2326 (decimal) / 0x0916 (hex). The first valid frame should be at offset 0x00.
Anyway, my program loops inside the whole file until it finds a valid header. It seems that 0x00 doesn't contain a valid header. -------------------- http://listening-tests.hydrogenaudio.org/sebastian/
|
|
|
|
May 22 2003, 21:49
Post
#12
|
|
![]() LAME developer Group: Developer Posts: 768 Joined: 22-September 01 Member No.: 5 |
well, the Xing/Lame header is trash for freeformat bitstreams.
your program seems to work correct, but you should not rely on the first frame you synchronize on only. CODE MPEG bitrate histogram - Copyright (C) 2000 Robert Hegemann
analysing: /home/robert/Sting - Desert Rose.mp3 frame # 123 (re-sync 123) kbps stereo free 122 32 0 40 0 48 0 56 0 64 0 80 0 96 0 112 0 128 0 160 0 192 0 224 0 256 0 320 0 This post has been edited by robert: May 22 2003, 21:58 |
|
|
|
May 23 2003, 14:39
Post
#13
|
|
![]() Group: Members Posts: 3621 Joined: 14-May 03 From: Bad Herrenalb Member No.: 6613 |
OK, problem fixed. The "bug" was in the "CheckValidHeader" function. My free format table entry had index 15 and the CheckValidHeader function reported bit rate index 0x0F (15) as non-valid MP3. Therefore it skipped some frames.
I am now checking only if the sync word is 2047 (decimal). I have tested it with MPEG 1, 2 and 2.5 files and it is always 2047. -------------------- http://listening-tests.hydrogenaudio.org/sebastian/
|
|
|
|
Jun 1 2003, 19:50
Post
#14
|
|
|
getID3() developer Group: Developer Posts: 252 Joined: 20-September 02 From: Kingston, ON Member No.: 3413 |
I just checked getID3() for free-format support and it was broken too
I also had the problem of bitrate table index 15 being null, but used for free-format (rather than index 0). Anyhow, getID3() now recognizes free-format MP3s, and calculates the correct bitrate, but only if a LAME/Xing-style header is present. QUOTE (robert @ May 22 2003 - 12:49 PM) well, the Xing/Lame header is trash for freeformat bitstreams. Can you elaborate on that? I in fact need the Xing/LAME header to properly handle free-format... The only way I can think to figure out free-format bitrate without the header is to scan the whole file byte by byte looking for sync patterns to calculate frame length - is there a better way to do that?[edit] I have headerless freeformat working fine now - what I do is scan the file from the beginning for the next occurance of the 4-byte synch pattern (or the alternate 4-byte synch pattern, with the padding bit flipped), and assume that distance is correct, and seek through the file to the next offset based on that frame length (since freeformat is CBR), and check to see if an good synch 4-byte pattern is found there (plus-or-minus 1 byte to account for padding or not). This method might not be the most efficient, but it works... and how often do you see free-format MP3s? This post has been edited by getID3(): Jun 1 2003, 22:00 -------------------- getID3() = PHP audio & video metadata parser: http://getid3.sourceforge.net
Current version: v1.7.0 (released January 19, 2004) |
|
|
|
Jun 2 2003, 08:37
Post
#15
|
|
![]() LAME developer Group: Developer Posts: 2950 Joined: 1-October 01 From: Nanterre, France Member No.: 138 |
The Lame tag was broken in case of freeformat. It is now fixed in the cvs version.
|
|
|
|
Jun 2 2003, 15:01
Post
#16
|
|
|
getID3() developer Group: Developer Posts: 252 Joined: 20-September 02 From: Kingston, ON Member No.: 3413 |
Can you elaborate? Broken in what sense?
-------------------- getID3() = PHP audio & video metadata parser: http://getid3.sourceforge.net
Current version: v1.7.0 (released January 19, 2004) |
|
|
|
Jun 2 2003, 15:10
Post
#17
|
|
![]() Group: Members Posts: 3621 Joined: 14-May 03 From: Bad Herrenalb Member No.: 6613 |
What about Dibrom's compile? I was able to calculate the correct data evaluating the LAME 3.90.3 header...
-------------------- http://listening-tests.hydrogenaudio.org/sebastian/
|
|
|
|
Jun 2 2003, 15:18
Post
#18
|
|
![]() LAME developer Group: Developer Posts: 2950 Joined: 1-October 01 From: Nanterre, France Member No.: 138 |
The Lame header was broken in case of freeformat, as the bitrate entry was 15 and not 0
|
|
|
|
Jun 2 2003, 19:59
Post
#19
|
|
![]() Group: Members Posts: 3621 Joined: 14-May 03 From: Bad Herrenalb Member No.: 6613 |
Well, shouldn't it be 15; 0 is "bad" and 15 is "free".
-------------------- http://listening-tests.hydrogenaudio.org/sebastian/
|
|
|
|
Jun 2 2003, 20:27
Post
#20
|
|
![]() LAME developer Group: Developer Posts: 768 Joined: 22-September 01 Member No.: 5 |
no, bitrate table value 0 means free format, 15 means illegal.
|
|
|
|
Jun 2 2003, 23:30
Post
#21
|
|
|
getID3() developer Group: Developer Posts: 252 Joined: 20-September 02 From: Kingston, ON Member No.: 3413 |
What versions of LAME was the index-15 problem present for free-format?
What version will it be fixed for? 3.94? -------------------- getID3() = PHP audio & video metadata parser: http://getid3.sourceforge.net
Current version: v1.7.0 (released January 19, 2004) |
|
|
|
Jun 3 2003, 07:56
Post
#22
|
|
![]() LAME developer Group: Developer Posts: 2950 Joined: 1-October 01 From: Nanterre, France Member No.: 138 |
Fixed in 3.94, present since I do not know wich version.
|
|
|
|
Jun 3 2003, 17:33
Post
#23
|
|
|
getID3() developer Group: Developer Posts: 252 Joined: 20-September 02 From: Kingston, ON Member No.: 3413 |
I just compressed 100kbps freeformat testfiles for all the 3.8x and 3.9x LAME versions I have, and this is what I found:
-------------------- getID3() = PHP audio & video metadata parser: http://getid3.sourceforge.net
Current version: v1.7.0 (released January 19, 2004) |
|
|
|
![]() ![]() |
|
Lo-Fi Version | Time is now: 20th June 2013 - 03:53 |