org.jaudiotagger.audio.mp3
Class MP3AudioHeader

java.lang.Object
  extended by org.jaudiotagger.audio.mp3.MP3AudioHeader
All Implemented Interfaces:
AudioHeader
Direct Known Subclasses:
ByteArrayMP3AudioHeader

public class MP3AudioHeader
extends java.lang.Object
implements AudioHeader

Represents the audio header of an MP3 File

The audio header consists of a number of audio frames. Because we are not trying to play the audio but only extract some information regarding the audio we only need to read the first audio frames to ensure that we have correctly identified them as audio frames and extracted the metadata we reuire.

Start of Audio id 0xFF (11111111) and then second byte anded with 0xE0(11100000). For example 2nd byte doesnt have to be 0xE0 is just has to have the top 3 signicant bits set. For example 0xFB (11111011) is a common occurence of the second match. The 2nd byte defines flags to indicate various mp3 values.

Having found these two values we then read the header which comprises these two bytes plus a further two to ensure this really is a MP3Header, sometimes the first frame is actually a dummy frame with summary information held within about the whole file, typically using a Xing Header or LAme Header. This is most useful when the file is variable bit rate, if the file is variable bit rate but does not use a summary header it will not be correctly identified as a VBR frame and the track length will be incorrectly calculated. Strictly speaking MP3 means Layer III file but MP2 Layer II), MP1 Layer I) and MPEG-2 files are sometimes used and named with the .mp3 suffix so this library attempts to supports all these formats.


Field Summary
private  long bitrate
           
private static int CONVERT_TO_KILOBITS
           
private static int CONVERTS_BYTE_TO_BITS
           
private  java.lang.String encoder
           
private static int FILE_BUFFER_SIZE
          After testing the average location of the first MP3Header bit was at 5000 bytes so this is why chosen as a default.
private  long fileSize
           
private static char isVbrIdentifier
           
static java.util.logging.Logger logger
           
private static int MIN_BUFFER_REMAINING_REQUIRED
           
protected  MPEGFrameHeader mp3FrameHeader
           
protected  VbriFrame mp3VbriFrame
           
protected  XingFrame mp3XingFrame
           
private static int NO_SECONDS_IN_HOUR
           
private  long numberOfFrames
           
private  long numberOfFramesEstimate
           
private  long startByte
           
private static java.text.SimpleDateFormat timeInFormat
           
private static java.text.SimpleDateFormat timeOutFormat
           
private static java.text.SimpleDateFormat timeOutOverAnHourFormat
           
private  double timePerFrame
           
private  double trackLength
           
private static java.lang.String TYPE_MP3
           
 
Constructor Summary
MP3AudioHeader()
           
MP3AudioHeader(java.io.File seekFile)
          Search for the first MP3Header in the file

The search starts from the start of the file, it is usually safer to use the alternative constructor that allows you to provide the length of the tag header as a parameter so the tag can be skipped over.

MP3AudioHeader(java.io.File seekFile, long startByte)
          Search for the first MP3Header in the file

Starts searching from location startByte, this is because there is likely to be an ID3TagHeader before the start of the audio.

 
Method Summary
 java.lang.String getBitRate()
           
 long getBitRateAsNumber()
           
 java.lang.String getChannels()
           
 java.lang.String getEmphasis()
           
 java.lang.String getEncoder()
           
 java.lang.String getEncodingType()
           
 java.lang.String getFormat()
           
 long getMp3StartByte()
          Returns the byte position of the first MP3 Frame that the file arguement refers to.
 java.lang.String getMpegLayer()
           
 java.lang.String getMpegVersion()
           
 long getNumberOfFrames()
           
 long getNumberOfFramesEstimate()
           
 double getPreciseTrackLength()
           
 java.lang.String getSampleRate()
           
 int getSampleRateAsNumber()
           
private  double getTimePerFrame()
           
 int getTrackLength()
           
 java.lang.String getTrackLengthAsString()
          Return the length in user friendly format
 boolean isCopyrighted()
           
private  boolean isNextFrameValid(java.io.File seekFile, long filePointerCount, java.nio.ByteBuffer bb, java.nio.channels.FileChannel fc)
          Called in some circumstances to check the next frame to ensure we have the correct audio header
 boolean isOriginal()
           
 boolean isPadding()
           
 boolean isPrivate()
           
 boolean isProtected()
           
 boolean isVariableBitRate()
           
 boolean seek(java.io.File seekFile, long startByte)
          Returns true if the first MP3 frame can be found for the MP3 file

This is the first byte of music data and not the ID3 Tag Frame.

protected  void setBitRate()
          Set bitrate in kbps, if Vbr use Xingheader if possible
protected  void setEncoder()
           
protected  void setFileSize(long fileSize)
          Set the size of the file, required in some calculations
protected  void setMp3StartByte(long startByte)
          Set the location of where the Audio file begins in the file
protected  void setNumberOfFrames()
          Set number of frames in this file, use Xing if exists otherwise ((File Size - Non Audio Part)/Frame Size)
protected  void setTimePerFrame()
          Set the time each frame contributes to the audio in fractions of seconds, the higher the sampling rate the shorter the audio segment provided by the frame, the number of samples is fixed by the MPEG Version and Layer
protected  void setTrackLength()
          Estimate the length of the audio track in seconds Calculation is Number of frames multiplied by the Time Per Frame using the first frame as a prototype Time Per Frame is the number of samples in the frame (which is defined by the MPEGVersion/Layer combination) divided by the sampling rate, i.e the higher the sampling rate the shorter the audio represented by the frame is going to be.
 java.lang.String toString()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

mp3FrameHeader

protected MPEGFrameHeader mp3FrameHeader

mp3XingFrame

protected XingFrame mp3XingFrame

mp3VbriFrame

protected VbriFrame mp3VbriFrame

fileSize

private long fileSize

startByte

private long startByte

timePerFrame

private double timePerFrame

trackLength

private double trackLength

numberOfFrames

private long numberOfFrames

numberOfFramesEstimate

private long numberOfFramesEstimate

bitrate

private long bitrate

encoder

private java.lang.String encoder

timeInFormat

private static final java.text.SimpleDateFormat timeInFormat

timeOutFormat

private static final java.text.SimpleDateFormat timeOutFormat

timeOutOverAnHourFormat

private static final java.text.SimpleDateFormat timeOutOverAnHourFormat

isVbrIdentifier

private static final char isVbrIdentifier
See Also:
Constant Field Values

CONVERT_TO_KILOBITS

private static final int CONVERT_TO_KILOBITS
See Also:
Constant Field Values

TYPE_MP3

private static final java.lang.String TYPE_MP3
See Also:
Constant Field Values

CONVERTS_BYTE_TO_BITS

private static final int CONVERTS_BYTE_TO_BITS
See Also:
Constant Field Values

logger

public static java.util.logging.Logger logger

FILE_BUFFER_SIZE

private static final int FILE_BUFFER_SIZE
After testing the average location of the first MP3Header bit was at 5000 bytes so this is why chosen as a default.

See Also:
Constant Field Values

MIN_BUFFER_REMAINING_REQUIRED

private static final int MIN_BUFFER_REMAINING_REQUIRED
See Also:
Constant Field Values

NO_SECONDS_IN_HOUR

private static final int NO_SECONDS_IN_HOUR
See Also:
Constant Field Values
Constructor Detail

MP3AudioHeader

public MP3AudioHeader()

MP3AudioHeader

public MP3AudioHeader(java.io.File seekFile)
               throws java.io.IOException,
                      InvalidAudioFrameException
Search for the first MP3Header in the file

The search starts from the start of the file, it is usually safer to use the alternative constructor that allows you to provide the length of the tag header as a parameter so the tag can be skipped over.

Parameters:
seekFile -
Throws:
java.io.IOException
InvalidAudioFrameException

MP3AudioHeader

public MP3AudioHeader(java.io.File seekFile,
                      long startByte)
               throws java.io.IOException,
                      InvalidAudioFrameException
Search for the first MP3Header in the file

Starts searching from location startByte, this is because there is likely to be an ID3TagHeader before the start of the audio. If this tagHeader contains unsynchronized information there is a possibility that it might be inaccurately identified as the start of the Audio data. Various checks are done in this code to prevent this happening but it cannot be guaranteed.

Of course if the startByte provided overstates the length of the tag header, this could mean the start of the MP3AudioHeader is missed, further checks are done within the MP3 class to recognize if this has occurred and take appropriate action.

Parameters:
seekFile -
startByte -
Throws:
java.io.IOException
InvalidAudioFrameException
Method Detail

seek

public boolean seek(java.io.File seekFile,
                    long startByte)
             throws java.io.IOException
Returns true if the first MP3 frame can be found for the MP3 file

This is the first byte of music data and not the ID3 Tag Frame. *

Parameters:
seekFile - MP3 file to seek
startByte - if there is an ID3v2tag we dont want to start reading from the start of the tag
Returns:
true if the first MP3 frame can be found
Throws:
java.io.IOException - on any I/O error

isNextFrameValid

private boolean isNextFrameValid(java.io.File seekFile,
                                 long filePointerCount,
                                 java.nio.ByteBuffer bb,
                                 java.nio.channels.FileChannel fc)
                          throws java.io.IOException
Called in some circumstances to check the next frame to ensure we have the correct audio header

Parameters:
seekFile -
filePointerCount -
bb -
fc -
Returns:
true if frame is valid
Throws:
java.io.IOException

setMp3StartByte

protected void setMp3StartByte(long startByte)
Set the location of where the Audio file begins in the file

Parameters:
startByte -

getMp3StartByte

public long getMp3StartByte()
Returns the byte position of the first MP3 Frame that the file arguement refers to. This is the first byte of music data and not the ID3 Tag Frame.

Returns:
the byte position of the first MP3 Frame

setNumberOfFrames

protected void setNumberOfFrames()
Set number of frames in this file, use Xing if exists otherwise ((File Size - Non Audio Part)/Frame Size)


getNumberOfFrames

public long getNumberOfFrames()
Returns:
The number of frames within the Audio File, calculated as accurrately as possible

getNumberOfFramesEstimate

public long getNumberOfFramesEstimate()
Returns:
The number of frames within the Audio File, calculated by dividing the filesize by the number of frames, this may not be the most accurate method available.

setTimePerFrame

protected void setTimePerFrame()
Set the time each frame contributes to the audio in fractions of seconds, the higher the sampling rate the shorter the audio segment provided by the frame, the number of samples is fixed by the MPEG Version and Layer


getTimePerFrame

private double getTimePerFrame()
Returns:
the the time each frame contributes to the audio in fractions of seconds

setTrackLength

protected void setTrackLength()
Estimate the length of the audio track in seconds Calculation is Number of frames multiplied by the Time Per Frame using the first frame as a prototype Time Per Frame is the number of samples in the frame (which is defined by the MPEGVersion/Layer combination) divided by the sampling rate, i.e the higher the sampling rate the shorter the audio represented by the frame is going to be.


getPreciseTrackLength

public double getPreciseTrackLength()
Returns:
Track Length in seconds

getTrackLength

public int getTrackLength()
Specified by:
getTrackLength in interface AudioHeader
Returns:
track length

getTrackLengthAsString

public java.lang.String getTrackLengthAsString()
Return the length in user friendly format

Returns:

getEncodingType

public java.lang.String getEncodingType()
Specified by:
getEncodingType in interface AudioHeader
Returns:
the audio file type

setBitRate

protected void setBitRate()
Set bitrate in kbps, if Vbr use Xingheader if possible


setEncoder

protected void setEncoder()

getBitRateAsNumber

public long getBitRateAsNumber()
Specified by:
getBitRateAsNumber in interface AudioHeader
Returns:
bitrate in kbps, no indicator is provided as to whether or not it is vbr

getBitRate

public java.lang.String getBitRate()
Specified by:
getBitRate in interface AudioHeader
Returns:
the BitRate of the Audio, to distinguish cbr from vbr we add a '~' for vbr.

getSampleRateAsNumber

public int getSampleRateAsNumber()
Specified by:
getSampleRateAsNumber in interface AudioHeader
Returns:
the sampling rate in Hz

getSampleRate

public java.lang.String getSampleRate()
Specified by:
getSampleRate in interface AudioHeader
Returns:
the sampling rate as string

getMpegVersion

public java.lang.String getMpegVersion()
Returns:
MPEG Version (1-3)

getMpegLayer

public java.lang.String getMpegLayer()
Returns:
MPEG Layer (1-3)

getFormat

public java.lang.String getFormat()
Specified by:
getFormat in interface AudioHeader
Returns:
the format of the audio (i.e. MPEG-1 Layer3)

getChannels

public java.lang.String getChannels()
Specified by:
getChannels in interface AudioHeader
Returns:
the Channel Mode such as Stero or Mono

getEmphasis

public java.lang.String getEmphasis()
Returns:
Emphasis

isVariableBitRate

public boolean isVariableBitRate()
Specified by:
isVariableBitRate in interface AudioHeader
Returns:
if the bitrate is variable, Xing header takes precedence if we have one

isProtected

public boolean isProtected()

isPrivate

public boolean isPrivate()

isCopyrighted

public boolean isCopyrighted()

isOriginal

public boolean isOriginal()

isPadding

public boolean isPadding()

getEncoder

public java.lang.String getEncoder()
Returns:
encoder

setFileSize

protected void setFileSize(long fileSize)
Set the size of the file, required in some calculations

Parameters:
fileSize -

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object
Returns:
a string represntation