com.limegroup.gnutella.mp3
Class MP3Info
java.lang.Object
com.limegroup.gnutella.mp3.MP3Info
- public final class MP3Info
- extends java.lang.Object
Provide MP3 file info derived from the file header data
- See Also:
#getLayer_* -> mp3 layer (3 or "Layer III", etc)
,
-> mode type strings (stereo, dual channel, etc)
,
-> available frequencies (32000, 44100, etc) khz
,
#getVersion_* -> mp3 file version (2.0, or "MPEG Version 2.0")
,
-> constant bit rates(CBR) (128, 256, etc) kps
,
ByteOrder
Constructor Summary |
MP3Info(java.lang.String file)
An MPEG audio file is built up from smaller parts called frames, which
are generally independent items. |
Method Summary |
int |
getBitRate()
|
java.lang.String |
getEmphasis()
Mp3 Emphasis
-> "none", "50/15 ms", null, "CCIT J.17" |
long |
getFileSize()
Bytes in the mp3 file |
int |
getFrequency()
The frequency is dependent on bitrate index and MPEG version
-> MPEG 2.5 - 32000, 16000, 8000
-> MPEG 2 - 22050, 24000, 16000
-> MPEG 1 - 44100, 48000, 32000 |
int |
getHeaderBitRate()
Based on the bitrate index found in the header
The header bit rate is based off the BITRATE_TABLE values using indexes
whereas the other bit rate is calculated directly without the table
both rates should be equal, excluding possible VBR discrepencies |
int |
getLayer_Numeric()
Layer formula:
4 - layerIndex
-> 1, 2, 3 |
java.lang.String |
getLayer_String()
Layer formula:
4 - layerIndex
-> null, "Layer III", "Layer II", "Layer I" |
long |
getLengthInSeconds()
Length in seconds formula:
-> fileSize / (bitrate * 100 / 8) |
java.lang.String |
getMode()
Output channel information
"Stereo", "Joint Stereo", "Dual Channel", "Single Channel" |
int |
getNumberOfFrames()
FrameSize formula
mpeg v1: FrameSize = 12 * BitRate / SampleRate + Padding
mpeg v2: FrameSize = 144 * BitRate / SampleRate + Padding
bitrate is kbps and sample rate in Hz, so multiply BitRate by 1000
Number of Frames formula
mp3 file length in bytes / frame size
the VBR header usually has the number of frames stored internally
!!Results may not be precise as frame calculation is not always exact. |
com.limegroup.gnutella.mp3.MP3Info.VBRHeader |
getVBRHeader()
VBR header containing Table of Contents and Quality |
double |
getVersion_Numeric()
Based on the version index
-> 2.5, 0.0, 2.0, 1.0 |
java.lang.String |
getVersion_String()
Based on the version index
-> "MPEG Version 2.5", null, "MPEG Version 2.0", "MPEG Version 1.0" |
boolean |
hasVariableBitRate()
Whether the bits per frame are not constant |
boolean |
isCoprighted()
Whether the copyright bit is flagged in the mp3 header |
boolean |
isOriginal()
Whether the original bit is flagged in the mp3 header |
boolean |
isPadded()
Whether padding bit is set; Padding is used to fit bit rates exactly. |
boolean |
isPrivate()
Whether the private bit is flagged in the mp3 header |
boolean |
isProtected()
Whether the protection bit is flagged in mp3 header
Indicates CRC; 16 bit crc follows file header |
boolean |
isRiffWav()
Whether this MP3 is embedded in a WAV file
RIFF(Resource Interchange File Format) is a tagged file structure
developed for multimedia resource files. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
MP3Info
public MP3Info(java.lang.String file)
throws java.io.IOException
- An MPEG audio file is built up from smaller parts called frames, which
are generally independent items. Each frame has its own header and audio
data that follows. There is NO MPEG file header; therefore, you can cut
any part of MPEG file and play it correctly (cut on frame boundaries!),
excluding MPEG 1 Layer III frames which are often dependent on another.
To read info about an MPEG file, you can find the first frame, read its
header and assume that the other frames are the same. Exceptions to this
are VBR (variable bit rate) and ABR (average bit rate) files. The frame
header is constituted by the very first four bytes (32bits) in a frame.
The first 11 bits are always set on(1) and they're called "frame sync".
Frame CRC is optional and 16 bits long; it follows the frame header.
After the CRC comes the audio data.
::EXAMPLE:: MP3 file header format (4 byte length or 32 bits)
byte[4] = { -1, -5, 80, 108 }
-1 << 24 + -5 << 16 + 80 << 08 + 108 << 0 {HdrCRC}
11111111 11101010 00110000 11000000 {0000}
AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM {ZZZZ}
Label, Position(bits), Description
A (31-21) Frame sync
All bits set (1)
B (20,19) MPEG Audio version ID
00 - MPEG Ver 2.5, 01 - reserved, 10 - Ver 2, 11 - Ver 1
Note: MPEG Ver 2.5 is not official; bit # 20 indicates 2.5
C (18,17) Layer description
00 - reserved, 01 - Layer III, 10 - Layer II, 11 - Layer I
D (16) Protection bit
0 - None, 1 - Protected by CRC (16bit crc follows header)
E (15,12) Bitrate index, version and layer
bits V1,L1 V1,L2 V1,L3 V2,L1 V2, L2 & L3
F (11,10)
G (9) Padding bit
0 - frame not padded, 1 - frame padded with one extra slot
Note: Padding is used to fit the bit rates exactly.
H (8) Private bit
0 - not private, 1 - private
Note: May be freely used for other needs of an application.
I (7,6) Channel Mode
00 - Stereo, 01 - Joint stereo, 10 - Dual (Stereo), 11 - Mono
J (5,4) Mode extension (Only if Joint stereo)
Used to join data; bits dynamically generated by an encoder.
K (3) Copyright
0 - Audio is not copyrighted, 1 - Audio is marked copyrighted
L (2) Original
0 - Copy of original media, 1 - Original media
M (1,0) Emphasis
00 - none, 01 - 50/15 ms, 10 - reserved, 11 - CCIT J.17
Z (32-35) CRC !!OPTIONAL!!
Note: NOT part of header, just appended on end when needed
We read in bytes from the beginning of the mp3 file looking for
the 4 byte header; we can't assume it starts at byte 0 because
ID3 tags may be prepended before the first valid header.
The loop below strolls through buffered chunks of the file
looking for the header. As an optimization, we check the first
10 bytes initially as it may contain the header; if it doesn't
we then check the first 10 bytes for an ID3v2 header and fetch
the tag's length, skipping those bytes leading us directly
to the header. If neither are found, it's a brute force search.
With each chunk, we step forward one byte at a time, and test
the current byte plus the next 3 bytes for a valid mp3 header.
- Throws:
java.io.IOException
- mp3 fileName had no valid header
getBitRate
public int getBitRate()
getEmphasis
public java.lang.String getEmphasis()
- Mp3 Emphasis
-> "none", "50/15 ms", null, "CCIT J.17"
- Returns:
- java.lang.String string reprensentation of emphasis
- See Also:
#getEmphasisIndex
getFileSize
public long getFileSize()
- Bytes in the mp3 file
- Returns:
- long
getFrequency
public int getFrequency()
- The frequency is dependent on bitrate index and MPEG version
-> MPEG 2.5 - 32000, 16000, 8000
-> MPEG 2 - 22050, 24000, 16000
-> MPEG 1 - 44100, 48000, 32000
- Returns:
- the current frequency [8000-48000 Hz]
- See Also:
#getVersionIndex
,
#getFrequencyIndex
getHeaderBitRate
public int getHeaderBitRate()
- Based on the bitrate index found in the header
The header bit rate is based off the BITRATE_TABLE values using indexes
whereas the other bit rate is calculated directly without the table
both rates should be equal, excluding possible VBR discrepencies
- Returns:
- int The bitrate in between 8 - 448 Kb/s .
- See Also:
getBitRate
getLayer_Numeric
public int getLayer_Numeric()
- Layer formula:
4 - layerIndex
-> 1, 2, 3
- Returns:
- int the Layer [1-3] in small int format
- See Also:
#getLayerIndex
getLayer_String
public java.lang.String getLayer_String()
- Layer formula:
4 - layerIndex
-> null, "Layer III", "Layer II", "Layer I"
- Returns:
- java.lang.String representation of Mp3 Layer
- See Also:
#getLayerIndex
getLengthInSeconds
public long getLengthInSeconds()
- Length in seconds formula:
-> fileSize / (bitrate * 100 / 8)
- Returns:
- long mp3 seconds
- See Also:
getFileSize()
,
getHeaderBitRate()
getMode
public java.lang.String getMode()
- Output channel information
"Stereo", "Joint Stereo", "Dual Channel", "Single Channel"
- Returns:
- java.lang.String Display representation of playing mode
- See Also:
#getModeIndex
getNumberOfFrames
public int getNumberOfFrames()
- FrameSize formula
mpeg v1: FrameSize = 12 * BitRate / SampleRate + Padding
mpeg v2: FrameSize = 144 * BitRate / SampleRate + Padding
bitrate is kbps and sample rate in Hz, so multiply BitRate by 1000
Number of Frames formula
mp3 file length in bytes / frame size
the VBR header usually has the number of frames stored internally
!!Results may not be precise as frame calculation is not always exact.
Programs like Winamp occasionaly return slightly different results.
For example, we don't exclude added frames like ID3 tags.
- Returns:
- int frames calculated from mp3 (possible vbr) header
getVBRHeader
public com.limegroup.gnutella.mp3.MP3Info.VBRHeader getVBRHeader()
- VBR header containing Table of Contents and Quality
- Returns:
- MP3Info.VBRHeader Variable Bit Rate header
getVersion_Numeric
public double getVersion_Numeric()
- Based on the version index
-> 2.5, 0.0, 2.0, 1.0
- Returns:
- double the MPEG version number
- See Also:
#getVersionIndex
getVersion_String
public java.lang.String getVersion_String()
- Based on the version index
-> "MPEG Version 2.5", null, "MPEG Version 2.0", "MPEG Version 1.0"
- Returns:
- java.lang.String representation of version
- See Also:
#getVersionIndex
hasVariableBitRate
public boolean hasVariableBitRate()
- Whether the bits per frame are not constant
- Returns:
- True if this file has a VBR
isCoprighted
public boolean isCoprighted()
- Whether the copyright bit is flagged in the mp3 header
- Returns:
- boolean true if flag found
isOriginal
public boolean isOriginal()
- Whether the original bit is flagged in the mp3 header
- Returns:
- boolean true if flag found
isPadded
public boolean isPadded()
- Whether padding bit is set; Padding is used to fit bit rates exactly.
:Example: 128k 44.1kHz layer II uses a lot of 418 bytes and some of
417 bytes long frames to get the exact 128k bitrate. For Layer I
slot is 32 bits long, Layer II and Layer III slot is 8 bits long.
- Returns:
- boolean true if flag found
isPrivate
public boolean isPrivate()
- Whether the private bit is flagged in the mp3 header
- Returns:
- boolean true if flag found
isProtected
public boolean isProtected()
- Whether the protection bit is flagged in mp3 header
Indicates CRC; 16 bit crc follows file header
- Returns:
- boolean true if flag found
isRiffWav
public boolean isRiffWav()
- Whether this MP3 is embedded in a WAV file
RIFF(Resource Interchange File Format) is a tagged file structure
developed for multimedia resource files. The structure of RIFF
is similar to the structure of an ElectronicArts IFF file. RIFF is
not actually a file format itself (since it does not represent a
specific kind of information), but its name contains the words
`interchange file format' in recognition of its roots in IFF.
::the beginning of file will start as follows::
RIFF ??Y
1 WAVE fmt
AAAA BBBB CCCC DDDD
A 4 bytes RIFF Tag
B 4 bytes File Size - Ignored for this test
C 4 bytes WAVE Tag
D 4 bytes fmt name
- Returns:
- boolean true if file is marked as Replay Gain RIFF-WAV
!!Doesn't gurantee file is a valid or playable RIFF-WAV