FileDocCategorySizeDatePackage
MPEGFrameHeader.javaAPI DocJaudiotagger 2.0.427812Fri May 06 14:34:48 BST 2011org.jaudiotagger.audio.mp3

MPEGFrameHeader

public class MPEGFrameHeader extends Object
Represents a MPEGFrameHeader, an MP3 is made up of a number of frames each frame starts with a four byte frame header.

Fields Summary
private static final int
BYTE_1
Constants for MP3 Frame header, each frame has a basic header of 4 bytes
private static final int
BYTE_2
private static final int
BYTE_3
private static final int
BYTE_4
public static final int
HEADER_SIZE
public static final int
SYNC_SIZE
Sync Value to identify the start of an MPEGFrame
public static final int
SYNC_BYTE1
public static final int
SYNC_BYTE2
public static final int
SYNC_BIT_ANDSAMPING_BYTE3
private static final byte[]
header
public static final Map
mpegVersionMap
Constants for MPEG Version
public static final int
VERSION_2_5
public static final int
VERSION_2
public static final int
VERSION_1
public static final Map
mpegLayerMap
Constants for MPEG Layer
public static final int
LAYER_I
public static final int
LAYER_II
public static final int
LAYER_III
public static final int
LAYER_I_SLOT_SIZE
Slot Size is dependent on Layer
public static final int
LAYER_II_SLOT_SIZE
public static final int
LAYER_III_SLOT_SIZE
private static final Map
bitrateMap
Bit Rates, the setBitrate varies for different Version and Layer
public static final Map
modeMap
Constants for Channel mode
public static final int
MODE_STEREO
public static final int
MODE_JOINT_STEREO
public static final int
MODE_DUAL_CHANNEL
public static final int
MODE_MONO
private static final Map
emphasisMap
Constants for Emphasis
public static final int
EMPHASIS_NONE
public static final int
EMPHASIS_5015MS
public static final int
EMPHASIS_RESERVED
public static final int
EMPHASIS_CCITT
private static final Map
modeExtensionMap
private static final int
MODE_EXTENSION_NONE
private static final int
MODE_EXTENSION_ONE
private static final int
MODE_EXTENSION_TWO
private static final int
MODE_EXTENSION_THREE
private static final Map
modeExtensionLayerIIIMap
private static final int
MODE_EXTENSION_OFF_OFF
private static final int
MODE_EXTENSION_ON_OFF
private static final int
MODE_EXTENSION_OFF_ON
private static final int
MODE_EXTENSION_ON_ON
private static final Map
samplingRateMap
Sampling Rate in Hz
private static final Map
samplingV1Map
private static final Map
samplingV2Map
private static final Map
samplingV25Map
private static final Map
samplesPerFrameMap
private static final Map
samplesPerFrameV1Map
private static final Map
samplesPerFrameV2Map
private static final Map
samplesPerFrameV25Map
private static final int
SCALE_BY_THOUSAND
private static final int
LAYER_I_FRAME_SIZE_COEFFICIENT
private static final int
LAYER_II_FRAME_SIZE_COEFFICIENT
private static final int
LAYER_III_FRAME_SIZE_COEFFICIENT
private static final int
MASK_MP3_ID
MP3 Frame Header bit mask
private static final int
MASK_MP3_VERSION
MP3 version, confusingly for MP3s the version is 1.
private static final int
MASK_MP3_LAYER
MP3 Layer, for MP3s the Layer is 3
private static final int
MASK_MP3_PROTECTION
Does it include a CRC Checksum at end of header, this can be used to check the header.
private static final int
MASK_MP3_BITRATE
The setBitrate of this MP3
private static final int
MASK_MP3_FREQUENCY
The sampling/frequency rate
private static final int
MASK_MP3_PADDING
An extra padding bit is sometimes used to make sure frames are exactly the right length
private static final int
MASK_MP3_PRIVACY
Private bit set, for application specific
private static final int
MASK_MP3_MODE
Channel Mode, Stero/Mono/Dual Channel
private static final int
MASK_MP3_MODE_EXTENSION
MP3 Frame Header bit mask
private static final int
MASK_MP3_COPY
MP3 Frame Header bit mask
private static final int
MASK_MP3_HOME
MP3 Frame Header bit mask
private static final int
MASK_MP3_EMPHASIS
MP3 Frame Header bit mask
private byte[]
mpegBytes
private int
version
The version of this MPEG frame (see the constants)
private String
versionAsString
private int
layer
Contains the mpeg layer of this frame (see constants)
private String
layerAsString
private Integer
bitRate
Bitrate of this frame
private int
channelMode
Channel Mode of this Frame (see constants)
private String
channelModeAsString
Channel Mode of this Frame As English String
private int
emphasis
Emphasis of this frame
private String
emphasisAsString
Emphasis mode string
private String
modeExtension
Mode Extension
private boolean
isPadding
Flag indicating if this frame has padding byte
private boolean
isCopyrighted
Flag indicating if this frame contains copyrighted material
private boolean
isOriginal
Flag indicating if this frame contains original material
private boolean
isProtected
Flag indicating if this frame is protected
private boolean
isPrivate
Flag indicating if this frame is private
private Integer
samplingRate
Constructors Summary
private MPEGFrameHeader()
Hide Constructor

throws
org.jaudiotagger.audio.exceptions.InvalidAudioFrameException


    
private MPEGFrameHeader(byte[] b)
Try and create a new MPEG frame with the given byte array and decodes its contents If decoding header causes a problem it is not a valid header

param
b the array of bytes representing this mpeg frame
throws
InvalidAudioFrameException if does not match expected format

        mpegBytes = b;
        setBitrate();
        setVersion();
        setLayer();
        setProtected();
        setSamplingRate();
        setPadding();
        setPrivate();
        setChannelMode();
        setModeExtension();
        setCopyrighted();
        setOriginal();
        setEmphasis();
    
Methods Summary
public java.lang.IntegergetBitRate()

        return bitRate;
    
public intgetChannelMode()

        return channelMode;
    
public java.lang.StringgetChannelModeAsString()

        return channelModeAsString;
    
public intgetEmphasis()

        return emphasis;
    
public java.lang.StringgetEmphasisAsString()

        return emphasisAsString;
    
public intgetFrameLength()

        switch (version)
        {
            case VERSION_2:
            case VERSION_2_5:
                switch (layer)
                {
                    case LAYER_I:
                        return (LAYER_I_FRAME_SIZE_COEFFICIENT * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength()) * LAYER_I_SLOT_SIZE;

                    case LAYER_II:
                        return (LAYER_II_FRAME_SIZE_COEFFICIENT ) * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength() * LAYER_II_SLOT_SIZE;

                    case LAYER_III:
                        if (this.getChannelMode() == MODE_MONO)
                        {
                            return (LAYER_III_FRAME_SIZE_COEFFICIENT / 2 ) * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength() * LAYER_III_SLOT_SIZE;
                        }
                        else
                        {
                            return (LAYER_III_FRAME_SIZE_COEFFICIENT) * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength() * LAYER_III_SLOT_SIZE;
                        }


                    default:
                        throw new RuntimeException("Mp3 Unknown Layer:" + layer);

                }


            case VERSION_1:
                switch (layer)
                {
                    case LAYER_I:
                        return (LAYER_I_FRAME_SIZE_COEFFICIENT * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength()) * LAYER_I_SLOT_SIZE;

                    case LAYER_II:
                        return LAYER_II_FRAME_SIZE_COEFFICIENT * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength() * LAYER_II_SLOT_SIZE;

                    case LAYER_III:
                        return LAYER_III_FRAME_SIZE_COEFFICIENT * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength() * LAYER_III_SLOT_SIZE;

                    default:
                        throw new RuntimeException("Mp3 Unknown Layer:" + layer);

                }

            default:
                throw new RuntimeException("Mp3 Unknown Version:" + version);

        }
    
public intgetLayer()
Gets the layerVersion attribute of the MPEGFrame object

return
The layerVersion value



                     
      
    
        return layer;
    
public java.lang.StringgetLayerAsString()

        return layerAsString;
    
public java.lang.StringgetModeExtension()

        return modeExtension;
    
public intgetNoOfSamples()
Get the number of samples in a frame, all frames in a file have a set number of samples as defined by their MPEG Versiona and Layer

return

        Integer noOfSamples = samplesPerFrameMap.get(version).get(layer);
        return noOfSamples;
    
public intgetNumberOfChannels()
Gets the number of channels

return
The setChannelMode value

        switch (channelMode)
        {
            case MODE_DUAL_CHANNEL:
                return 2;
            case MODE_JOINT_STEREO:
                return 2;
            case MODE_MONO:
                return 1;
            case MODE_STEREO:
                return 2;
            default:
                return 0;
        }
    
public intgetPaddingLength()
Gets the paddingLength attribute of the MPEGFrame object

return
The paddingLength value

        if (isPadding())
        {
            return 1;
        }
        else
        {
            return 0;
        }
    
public java.lang.IntegergetSamplingRate()

        return samplingRate;
    
public intgetVersion()
Gets the mPEGVersion attribute of the MPEGFrame object

return
The mPEGVersion value

        return version;
    
public java.lang.StringgetVersionAsString()

        return versionAsString;
    
public booleanisCopyrighted()

        return isCopyrighted;
    
public static booleanisMPEGFrame(java.nio.ByteBuffer bb)
Gets the MPEGFrame attribute of the MPEGFrame object

param
bb
return
The mPEGFrame value

        int position = bb.position();
        return (((bb.get(position) & SYNC_BYTE1) == SYNC_BYTE1)
                && ((bb.get(position + 1) & SYNC_BYTE2) == SYNC_BYTE2)
                && ((bb.get(position + 2) & SYNC_BIT_ANDSAMPING_BYTE3) != SYNC_BIT_ANDSAMPING_BYTE3));
    
public booleanisOriginal()

        return isOriginal;
    
public booleanisPadding()

        return isPadding;
    
public booleanisPrivate()

        return isPrivate;
    
public booleanisProtected()

        return isProtected;
    
public booleanisVariableBitRate()

        return false;
    
public static org.jaudiotagger.audio.mp3.MPEGFrameHeaderparseMPEGHeader(java.nio.ByteBuffer bb)
Parse the MPEGFrameHeader of an MP3File, file pointer returns at end of the frame header

param
bb the byte buffer containing the header
return
throws
InvalidAudioFrameException if there is no header at this point

        int position = bb.position();
        bb.get(header, 0, HEADER_SIZE);
        bb.position(position);
        MPEGFrameHeader frameHeader = new MPEGFrameHeader(header);

        return frameHeader;
    
private voidsetBitrate()
Get the setBitrate of this frame

throws
org.jaudiotagger.audio.exceptions.InvalidAudioFrameException

        /* BitRate, get by checking header setBitrate bits and MPEG Version and Layer */
        int bitRateIndex = mpegBytes[BYTE_3] & MASK_MP3_BITRATE | mpegBytes[BYTE_2] & MASK_MP3_ID | mpegBytes[BYTE_2] & MASK_MP3_LAYER;

        bitRate = bitrateMap.get(bitRateIndex);
        if (bitRate == null)
        {
            throw new InvalidAudioFrameException("Invalid bitrate");
        }
    
private voidsetChannelMode()
Set the Mpeg channel mode of this frame as a constant (see constants)

throws
org.jaudiotagger.audio.exceptions.InvalidAudioFrameException

        channelMode = (mpegBytes[BYTE_4] & MASK_MP3_MODE) >>> 6;
        channelModeAsString = modeMap.get(channelMode);
        if (channelModeAsString == null)
        {
            throw new InvalidAudioFrameException("Invalid channel mode");
        }
    
private voidsetCopyrighted()
Gets the copyrighted attribute of the MPEGFrame object

        isCopyrighted = (mpegBytes[BYTE_4] & MASK_MP3_COPY) != 0;
    
private voidsetEmphasis()
Get the setEmphasis mode of this frame in a string representation

throws
org.jaudiotagger.audio.exceptions.InvalidAudioFrameException

        emphasis = mpegBytes[BYTE_4] & MASK_MP3_EMPHASIS;
        emphasisAsString = emphasisMap.get(emphasis);
        if (getEmphasisAsString() == null)
        {
            throw new InvalidAudioFrameException("Invalid emphasis");
        }
    
private voidsetLayer()
Get the layer version of this frame as a constant int value (see constants)

throws
org.jaudiotagger.audio.exceptions.InvalidAudioFrameException

        layer = (mpegBytes[BYTE_2] & MASK_MP3_LAYER) >>> 1;
        layerAsString = mpegLayerMap.get(layer);
        if (layerAsString == null)
        {
            throw new InvalidAudioFrameException("Invalid Layer");
        }
    
private voidsetModeExtension()
Sets the string representation of the mode extension of this frame

throws
org.jaudiotagger.audio.exceptions.InvalidAudioFrameException

        int index = (mpegBytes[BYTE_4] & MASK_MP3_MODE_EXTENSION) >> 4;
        if (layer == LAYER_III)
        {
            modeExtension = modeExtensionLayerIIIMap.get(index);
            if (getModeExtension() == null)
            {
                throw new InvalidAudioFrameException("Invalid Mode Extension");
            }
        }
        else
        {
            modeExtension = modeExtensionMap.get(index);
            if (getModeExtension() == null)
            {
                throw new InvalidAudioFrameException("Invalid Mode Extension");
            }
        }
    
private voidsetOriginal()
Sets the original attribute of the MPEGFrame object

        isOriginal = (mpegBytes[BYTE_4] & MASK_MP3_HOME) != 0;
    
private voidsetPadding()
Set whether this frame uses padding bytes

        isPadding = (mpegBytes[BYTE_3] & MASK_MP3_PADDING) != 0;
    
private voidsetPrivate()
Sets the private attribute of the MPEGFrame object

        isPrivate = (mpegBytes[BYTE_3] & MASK_MP3_PRIVACY) != 0;
    
private voidsetProtected()
Sets the protected attribute of the MPEGFrame object

        isProtected = (mpegBytes[BYTE_2] & MASK_MP3_PROTECTION) == 0x00;
    
private voidsetSamplingRate()
set the sampling rate in Hz of this frame

throws
org.jaudiotagger.audio.exceptions.InvalidAudioFrameException

        //Frequency
        int index = (mpegBytes[BYTE_3] & MASK_MP3_FREQUENCY) >>> 2;
        Map<Integer, Integer> samplingRateMapForVersion = samplingRateMap.get(version);
        if (samplingRateMapForVersion == null)
        {
            throw new InvalidAudioFrameException("Invalid version");
        }
        samplingRate = samplingRateMapForVersion.get(index);
        if (samplingRate == null)
        {
            throw new InvalidAudioFrameException("Invalid sampling rate");
        }
    
private voidsetVersion()
Set the version of this frame as an int value (see constants)

throws
org.jaudiotagger.audio.exceptions.InvalidAudioFrameException

        //MPEG Version
        version = (byte) ((mpegBytes[BYTE_2] & MASK_MP3_VERSION) >> 3);
        versionAsString = mpegVersionMap.get(version);
        if (versionAsString == null)
        {
            throw new InvalidAudioFrameException("Invalid mpeg version");
        }
    
public java.lang.StringtoString()

return
a string represntation

        return " mpeg frameheader:" + " frame length:" + getFrameLength() + " version:" + versionAsString + " layer:" + layerAsString + " channelMode:" + channelModeAsString + " noOfSamples:" + getNoOfSamples() + " samplingRate:" + samplingRate + " isPadding:" + isPadding + " isProtected:" + isProtected + " isPrivate:" + isPrivate + " isCopyrighted:" + isCopyrighted + " isOriginal:" + isCopyrighted + " isVariableBitRate" + this.isVariableBitRate() + " header as binary:" + AbstractTagDisplayFormatter.displayAsBinary(mpegBytes[BYTE_1]) + " " + AbstractTagDisplayFormatter.displayAsBinary(mpegBytes[BYTE_2]) + " " + AbstractTagDisplayFormatter.displayAsBinary(mpegBytes[BYTE_3]) + " " + AbstractTagDisplayFormatter.displayAsBinary(mpegBytes[BYTE_4]);