Coverage Report - org.jaudiotagger.audio.mp3.MPEGFrameHeader
 
Classes in this File Line Coverage Branch Coverage Complexity
MPEGFrameHeader
94%
252/268
74%
43/58
2.368
 
 1  
 /**
 2  
  * @author : Paul Taylor
 3  
  * <p/>
 4  
  * Version @version:$Id: MPEGFrameHeader.java 836 2009-11-12 15:44:07Z paultaylor $
 5  
  * Date :${DATE}
 6  
  * <p/>
 7  
  * Jaikoz Copyright Copyright (C) 2003 -2005 JThink Ltd
 8  
  */
 9  
 package org.jaudiotagger.audio.mp3;
 10  
 
 11  
 import org.jaudiotagger.FileConstants;
 12  
 import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
 13  
 import org.jaudiotagger.logging.AbstractTagDisplayFormatter;
 14  
 
 15  
 import java.nio.ByteBuffer;
 16  
 import java.util.HashMap;
 17  
 import java.util.Map;
 18  
 
 19  
 
 20  
 /**
 21  
  * Represents a MPEGFrameHeader, an MP3 is made up of a number of frames each frame starts with a four
 22  
  * byte frame header.
 23  
  */
 24  
 @SuppressWarnings({"PointlessArithmeticExpression"})
 25  
 public class MPEGFrameHeader
 26  
 {
 27  
     /**
 28  
      * Constants for MP3 Frame header, each frame has a basic header of
 29  
      * 4 bytes
 30  
      */
 31  
     private static final int BYTE_1 = 0;
 32  
     private static final int BYTE_2 = 1;
 33  
     private static final int BYTE_3 = 2;
 34  
     private static final int BYTE_4 = 3;
 35  
     public static final int HEADER_SIZE = 4;
 36  
 
 37  
     /**
 38  
      * Sync Value to identify the start of an MPEGFrame
 39  
      */
 40  
     public static final int SYNC_SIZE = 2;
 41  
 
 42  
     public static final int SYNC_BYTE1 = 0xFF;
 43  
     public static final int SYNC_BYTE2 = 0xE0;
 44  
 
 45  4
     private static final byte[] header = new byte[HEADER_SIZE];
 46  
 
 47  
 
 48  
     /**
 49  
      * Constants for MPEG Version
 50  
      */
 51  4
     public static final Map<Integer, String> mpegVersionMap = new HashMap<Integer, String>();
 52  
     public final static int VERSION_2_5 = 0;
 53  
     public final static int VERSION_2 = 2;
 54  
     public final static int VERSION_1 = 3;
 55  
 
 56  
     static
 57  
     {
 58  4
         mpegVersionMap.put(VERSION_2_5, "MPEG-2.5");
 59  4
         mpegVersionMap.put(VERSION_2, "MPEG-2");
 60  4
         mpegVersionMap.put(VERSION_1, "MPEG-1");
 61  
     }
 62  
 
 63  
     /**
 64  
      * Constants for MPEG Layer
 65  
      */
 66  4
     public static final Map<Integer, String> mpegLayerMap = new HashMap<Integer, String>();
 67  
     public final static int LAYER_I = 3;
 68  
     public final static int LAYER_II = 2;
 69  
     public final static int LAYER_III = 1;
 70  
 
 71  
     static
 72  
     {
 73  4
         mpegLayerMap.put(LAYER_I, "Layer 1");
 74  4
         mpegLayerMap.put(LAYER_II, "Layer 2");
 75  4
         mpegLayerMap.put(LAYER_III, "Layer 3");
 76  
     }
 77  
 
 78  
     /**
 79  
      * Slot Size is dependent on Layer
 80  
      */
 81  
     public final static int LAYER_I_SLOT_SIZE = 4;
 82  
     public final static int LAYER_II_SLOT_SIZE = 1;
 83  
     public final static int LAYER_III_SLOT_SIZE = 1;
 84  
 
 85  
     /**
 86  
      * Bit Rates, the setBitrate varies for different Version and Layer
 87  
      */
 88  4
     private static final Map<Integer, Integer> bitrateMap = new HashMap<Integer, Integer>();
 89  
 
 90  
     static
 91  
     {
 92  
         // MPEG-1, Layer I (E)
 93  4
         bitrateMap.put(0x1E, 32);
 94  4
         bitrateMap.put(0x2E, 64);
 95  4
         bitrateMap.put(0x3E, 96);
 96  4
         bitrateMap.put(0x4E, 128);
 97  4
         bitrateMap.put(0x5E, 160);
 98  4
         bitrateMap.put(0x6E, 192);
 99  4
         bitrateMap.put(0x7E, 224);
 100  4
         bitrateMap.put(0x8E, 256);
 101  4
         bitrateMap.put(0x9E, 288);
 102  4
         bitrateMap.put(0xAE, 320);
 103  4
         bitrateMap.put(0xBE, 352);
 104  4
         bitrateMap.put(0xCE, 384);
 105  4
         bitrateMap.put(0xDE, 416);
 106  4
         bitrateMap.put(0xEE, 448);
 107  
         // MPEG-1, Layer II (C)
 108  4
         bitrateMap.put(0x1C, 32);
 109  4
         bitrateMap.put(0x2C, 48);
 110  4
         bitrateMap.put(0x3C, 56);
 111  4
         bitrateMap.put(0x4C, 64);
 112  4
         bitrateMap.put(0x5C, 80);
 113  4
         bitrateMap.put(0x6C, 96);
 114  4
         bitrateMap.put(0x7C, 112);
 115  4
         bitrateMap.put(0x8C, 128);
 116  4
         bitrateMap.put(0x9C, 160);
 117  4
         bitrateMap.put(0xAC, 192);
 118  4
         bitrateMap.put(0xBC, 224);
 119  4
         bitrateMap.put(0xCC, 256);
 120  4
         bitrateMap.put(0xDC, 320);
 121  4
         bitrateMap.put(0xEC, 384);
 122  
         // MPEG-1, Layer III (A)
 123  4
         bitrateMap.put(0x1A, 32);
 124  4
         bitrateMap.put(0x2A, 40);
 125  4
         bitrateMap.put(0x3A, 48);
 126  4
         bitrateMap.put(0x4A, 56);
 127  4
         bitrateMap.put(0x5A, 64);
 128  4
         bitrateMap.put(0x6A, 80);
 129  4
         bitrateMap.put(0x7A, 96);
 130  4
         bitrateMap.put(0x8A, 112);
 131  4
         bitrateMap.put(0x9A, 128);
 132  4
         bitrateMap.put(0xAA, 160);
 133  4
         bitrateMap.put(0xBA, 192);
 134  4
         bitrateMap.put(0xCA, 224);
 135  4
         bitrateMap.put(0xDA, 256);
 136  4
         bitrateMap.put(0xEA, 320);
 137  
         // MPEG-2, Layer I (6)
 138  4
         bitrateMap.put(0x16, 32);
 139  4
         bitrateMap.put(0x26, 48);
 140  4
         bitrateMap.put(0x36, 56);
 141  4
         bitrateMap.put(0x46, 64);
 142  4
         bitrateMap.put(0x56, 80);
 143  4
         bitrateMap.put(0x66, 96);
 144  4
         bitrateMap.put(0x76, 112);
 145  4
         bitrateMap.put(0x86, 128);
 146  4
         bitrateMap.put(0x96, 144);
 147  4
         bitrateMap.put(0xA6, 160);
 148  4
         bitrateMap.put(0xB6, 176);
 149  4
         bitrateMap.put(0xC6, 192);
 150  4
         bitrateMap.put(0xD6, 224);
 151  4
         bitrateMap.put(0xE6, 256);
 152  
         // MPEG-2, Layer II (4)
 153  4
         bitrateMap.put(0x14, 8);
 154  4
         bitrateMap.put(0x24, 16);
 155  4
         bitrateMap.put(0x34, 24);
 156  4
         bitrateMap.put(0x44, 32);
 157  4
         bitrateMap.put(0x54, 40);
 158  4
         bitrateMap.put(0x64, 48);
 159  4
         bitrateMap.put(0x74, 56);
 160  4
         bitrateMap.put(0x84, 64);
 161  4
         bitrateMap.put(0x94, 80);
 162  4
         bitrateMap.put(0xA4, 96);
 163  4
         bitrateMap.put(0xB4, 112);
 164  4
         bitrateMap.put(0xC4, 128);
 165  4
         bitrateMap.put(0xD4, 144);
 166  4
         bitrateMap.put(0xE4, 160);
 167  
         // MPEG-2, Layer III (2)
 168  4
         bitrateMap.put(0x12, 8);
 169  4
         bitrateMap.put(0x22, 16);
 170  4
         bitrateMap.put(0x32, 24);
 171  4
         bitrateMap.put(0x42, 32);
 172  4
         bitrateMap.put(0x52, 40);
 173  4
         bitrateMap.put(0x62, 48);
 174  4
         bitrateMap.put(0x72, 56);
 175  4
         bitrateMap.put(0x82, 64);
 176  4
         bitrateMap.put(0x92, 80);
 177  4
         bitrateMap.put(0xA2, 96);
 178  4
         bitrateMap.put(0xB2, 112);
 179  4
         bitrateMap.put(0xC2, 128);
 180  4
         bitrateMap.put(0xD2, 144);
 181  4
         bitrateMap.put(0xE2, 160);
 182  
     }
 183  
 
 184  
     /**
 185  
      * Constants for Channel mode
 186  
      */
 187  4
     protected static final Map<Integer, String> modeMap = new HashMap<Integer, String>();
 188  
     public final static int MODE_STEREO = 0;
 189  
     public final static int MODE_JOINT_STEREO = 1;
 190  
     public final static int MODE_DUAL_CHANNEL = 2;
 191  
     public final static int MODE_MONO = 3;
 192  
 
 193  
     static
 194  
     {
 195  4
         modeMap.put(MODE_STEREO, "Stereo");
 196  4
         modeMap.put(MODE_JOINT_STEREO, "Joint Stereo");
 197  4
         modeMap.put(MODE_DUAL_CHANNEL, "Dual");
 198  4
         modeMap.put(MODE_MONO, "Mono");
 199  
     }
 200  
 
 201  
     /**
 202  
      * Constants for Emphasis
 203  
      */
 204  4
     private static final Map<Integer, String> emphasisMap = new HashMap<Integer, String>();
 205  
     public final static int EMPHASIS_NONE = 0;
 206  
     public final static int EMPHASIS_5015MS = 1;
 207  
     public final static int EMPHASIS_RESERVED = 2;
 208  
     public final static int EMPHASIS_CCITT = 3;
 209  
 
 210  
     static
 211  
     {
 212  4
         emphasisMap.put(EMPHASIS_NONE, "None");
 213  4
         emphasisMap.put(EMPHASIS_5015MS, "5015MS");
 214  4
         emphasisMap.put(EMPHASIS_RESERVED, "Reserved");
 215  4
         emphasisMap.put(EMPHASIS_CCITT, "CCITT");
 216  
     }
 217  
 
 218  
 
 219  4
     private static final Map<Integer, String> modeExtensionMap = new HashMap<Integer, String>();
 220  
     private final static int MODE_EXTENSION_NONE = 0;
 221  
     private final static int MODE_EXTENSION_ONE = 1;
 222  
     private final static int MODE_EXTENSION_TWO = 2;
 223  
     private final static int MODE_EXTENSION_THREE = 3;
 224  
 
 225  4
     private static final Map<Integer, String> modeExtensionLayerIIIMap = new HashMap<Integer, String>();
 226  
     private final static int MODE_EXTENSION_OFF_OFF = 0;
 227  
     private final static int MODE_EXTENSION_ON_OFF = 1;
 228  
     private final static int MODE_EXTENSION_OFF_ON = 2;
 229  
     private final static int MODE_EXTENSION_ON_ON = 3;
 230  
 
 231  
     static
 232  
     {
 233  4
         modeExtensionMap.put(MODE_EXTENSION_NONE, "4-31");
 234  4
         modeExtensionMap.put(MODE_EXTENSION_ONE, "8-31");
 235  4
         modeExtensionMap.put(MODE_EXTENSION_TWO, "12-31");
 236  4
         modeExtensionMap.put(MODE_EXTENSION_THREE, "16-31");
 237  
 
 238  4
         modeExtensionLayerIIIMap.put(MODE_EXTENSION_OFF_OFF, "off-off");
 239  4
         modeExtensionLayerIIIMap.put(MODE_EXTENSION_ON_OFF, "on-off");
 240  4
         modeExtensionLayerIIIMap.put(MODE_EXTENSION_OFF_ON, "off-on");
 241  4
         modeExtensionLayerIIIMap.put(MODE_EXTENSION_ON_ON, "on-on");
 242  
     }
 243  
 
 244  
     /**
 245  
      * Sampling Rate in Hz
 246  
      */
 247  4
     private static final Map<Integer, Map<Integer, Integer>> samplingRateMap = new HashMap<Integer, Map<Integer, Integer>>();
 248  4
     private static final Map<Integer, Integer> samplingV1Map = new HashMap<Integer, Integer>();
 249  4
     private static final Map<Integer, Integer> samplingV2Map = new HashMap<Integer, Integer>();
 250  4
     private static final Map<Integer, Integer> samplingV25Map = new HashMap<Integer, Integer>();
 251  
 
 252  
     static
 253  
     {
 254  4
         samplingV1Map.put(0, 44100);
 255  4
         samplingV1Map.put(1, 48000);
 256  4
         samplingV1Map.put(2, 32000);
 257  
 
 258  4
         samplingV2Map.put(0, 22050);
 259  4
         samplingV2Map.put(1, 24000);
 260  4
         samplingV2Map.put(2, 16000);
 261  
 
 262  4
         samplingV25Map.put(0, 11025);
 263  4
         samplingV25Map.put(1, 12000);
 264  4
         samplingV25Map.put(2, 8000);
 265  
 
 266  4
         samplingRateMap.put(VERSION_1, samplingV1Map);
 267  4
         samplingRateMap.put(VERSION_2, samplingV2Map);
 268  4
         samplingRateMap.put(VERSION_2_5, samplingV25Map);
 269  
     }
 270  
 
 271  
     /* Samples Per Frame */
 272  4
     private static final Map<Integer, Map<Integer, Integer>> samplesPerFrameMap = new HashMap<Integer, Map<Integer, Integer>>();
 273  4
     private static final Map<Integer, Integer> samplesPerFrameV1Map = new HashMap<Integer, Integer>();
 274  4
     private static final Map<Integer, Integer> samplesPerFrameV2Map = new HashMap<Integer, Integer>();
 275  4
     private static final Map<Integer, Integer> samplesPerFrameV25Map = new HashMap<Integer, Integer>();
 276  
 
 277  
     static
 278  
     {
 279  4
         samplesPerFrameV1Map.put(LAYER_I, 384);
 280  4
         samplesPerFrameV1Map.put(LAYER_II, 1152);
 281  4
         samplesPerFrameV1Map.put(LAYER_III, 1152);
 282  
 
 283  4
         samplesPerFrameV2Map.put(LAYER_I, 384);
 284  4
         samplesPerFrameV2Map.put(LAYER_II, 1152);
 285  4
         samplesPerFrameV2Map.put(LAYER_III, 1152);
 286  
 
 287  4
         samplesPerFrameV25Map.put(LAYER_I, 384);
 288  4
         samplesPerFrameV25Map.put(LAYER_II, 1152);
 289  4
         samplesPerFrameV25Map.put(LAYER_III, 1152);
 290  
 
 291  4
         samplesPerFrameMap.put(VERSION_1, samplesPerFrameV1Map);
 292  4
         samplesPerFrameMap.put(VERSION_2, samplesPerFrameV2Map);
 293  4
         samplesPerFrameMap.put(VERSION_2_5, samplesPerFrameV25Map);
 294  
 
 295  4
     }
 296  
 
 297  
 
 298  
     private static final int SCALE_BY_THOUSAND = 1000;
 299  
     private static final int LAYER_I_FRAME_SIZE_COEFFICIENT = 12;
 300  
     private static final int LAYER_II_FRAME_SIZE_COEFFICIENT = 144;
 301  
     private static final int LAYER_III_FRAME_SIZE_COEFFICIENT = 144;
 302  
 
 303  
     /**
 304  
      * MP3 Frame Header bit mask
 305  
      */
 306  
     private static final int MASK_MP3_ID = FileConstants.BIT3;
 307  
 
 308  
     /**
 309  
      * MP3 version, confusingly for MP3s the version is 1.
 310  
      */
 311  
     private static final int MASK_MP3_VERSION = FileConstants.BIT4 | FileConstants.BIT3;
 312  
 
 313  
     /**
 314  
      * MP3 Layer, for MP3s the Layer is 3
 315  
      */
 316  
     private static final int MASK_MP3_LAYER = FileConstants.BIT2 | FileConstants.BIT1;
 317  
 
 318  
     /**
 319  
      * Does it include a CRC Checksum at end of header, this can be used to check the header.
 320  
      */
 321  
     private static final int MASK_MP3_PROTECTION = FileConstants.BIT0;
 322  
 
 323  
     /**
 324  
      * The setBitrate of this MP3
 325  
      */
 326  
     private static final int MASK_MP3_BITRATE = FileConstants.BIT7 | FileConstants.BIT6 | FileConstants.BIT5 | FileConstants.BIT4;
 327  
 
 328  
     /**
 329  
      * The sampling/frequency rate
 330  
      */
 331  
     private static final int MASK_MP3_FREQUENCY = FileConstants.BIT3 + FileConstants.BIT2;
 332  
 
 333  
     /**
 334  
      * An extra padding bit is sometimes used to make sure frames are exactly the right length
 335  
      */
 336  
     private static final int MASK_MP3_PADDING = FileConstants.BIT1;
 337  
 
 338  
     /**
 339  
      * Private bit set, for application specific
 340  
      */
 341  
     private static final int MASK_MP3_PRIVACY = FileConstants.BIT0;
 342  
 
 343  
     /**
 344  
      * Channel Mode, Stero/Mono/Dual Channel
 345  
      */
 346  
     private static final int MASK_MP3_MODE = FileConstants.BIT7 | FileConstants.BIT6;
 347  
 
 348  
     /**
 349  
      * MP3 Frame Header bit mask
 350  
      */
 351  
     private static final int MASK_MP3_MODE_EXTENSION = FileConstants.BIT5 | FileConstants.BIT4;
 352  
 
 353  
     /**
 354  
      * MP3 Frame Header bit mask
 355  
      */
 356  
     private static final int MASK_MP3_COPY = FileConstants.BIT3;
 357  
 
 358  
     /**
 359  
      * MP3 Frame Header bit mask
 360  
      */
 361  
     private static final int MASK_MP3_HOME = FileConstants.BIT2;
 362  
 
 363  
     /**
 364  
      * MP3 Frame Header bit mask
 365  
      */
 366  
     private static final int MASK_MP3_EMPHASIS = FileConstants.BIT1 | FileConstants.BIT0;
 367  
 
 368  
 
 369  
     private byte[] mpegBytes;
 370  
 
 371  
     /**
 372  
      * The version of this MPEG frame (see the constants)
 373  
      */
 374  
     private int version;
 375  
 
 376  
     private String versionAsString;
 377  
 
 378  
     /**
 379  
      * Contains the mpeg layer of this frame (see constants)
 380  
      */
 381  
     private int layer;
 382  
 
 383  
     private String layerAsString;
 384  
     /**
 385  
      * Bitrate of this frame
 386  
      */
 387  
     private Integer bitRate;
 388  
 
 389  
     /**
 390  
      * Channel Mode of this Frame (see constants)
 391  
      */
 392  
     private int channelMode;
 393  
 
 394  
     /**
 395  
      * Channel Mode of this Frame As English String
 396  
      */
 397  
     private String channelModeAsString;
 398  
 
 399  
     /**
 400  
      * Emphasis of this frame
 401  
      */
 402  
     private int emphasis;
 403  
 
 404  
     /**
 405  
      * Emphasis mode string
 406  
      */
 407  
     private String emphasisAsString;
 408  
 
 409  
     /**
 410  
      * Mode Extension
 411  
      */
 412  
     private String modeExtension;
 413  
 
 414  
     /**
 415  
      * Flag indicating if this frame has padding byte
 416  
      */
 417  
     private boolean isPadding;
 418  
 
 419  
     /**
 420  
      * Flag indicating if this frame contains copyrighted material
 421  
      */
 422  
     private boolean isCopyrighted;
 423  
 
 424  
     /**
 425  
      * Flag indicating if this frame contains original material
 426  
      */
 427  
     private boolean isOriginal;
 428  
 
 429  
     /**
 430  
      * Flag indicating if this frame is protected
 431  
      */
 432  
     private boolean isProtected;
 433  
 
 434  
 
 435  
     /**
 436  
      * Flag indicating if this frame is private
 437  
      */
 438  
     private boolean isPrivate;
 439  
 
 440  
     private Integer samplingRate;
 441  
 
 442  
 
 443  
     /**
 444  
      * Gets the layerVersion attribute of the MPEGFrame object
 445  
      *
 446  
      * @return The layerVersion value
 447  
      */
 448  
     public int getLayer()
 449  
     {
 450  120
         return layer;
 451  
     }
 452  
 
 453  
     public String getLayerAsString()
 454  
     {
 455  55
         return layerAsString;
 456  
     }
 457  
 
 458  
     /**
 459  
      * Gets the copyrighted attribute of the MPEGFrame object
 460  
      */
 461  
     private void setCopyrighted()
 462  
     {
 463  2268
         isCopyrighted = (mpegBytes[BYTE_4] & MASK_MP3_COPY) != 0;
 464  2268
     }
 465  
 
 466  
 
 467  
     /**
 468  
      * Set the version of this frame as an int value (see constants)
 469  
      * @throws org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
 470  
      */
 471  
     private void setVersion() throws InvalidAudioFrameException
 472  
     {
 473  
         //MPEG Version
 474  2481
         version = (byte) ((mpegBytes[BYTE_2] & MASK_MP3_VERSION) >> 3);
 475  2481
         versionAsString = mpegVersionMap.get(version);
 476  2481
         if (versionAsString == null)
 477  
         {
 478  0
             throw new InvalidAudioFrameException("Invalid mpeg version");
 479  
         }
 480  2481
     }
 481  
 
 482  
     /**
 483  
      * Sets the original attribute of the MPEGFrame object
 484  
      */
 485  
     private void setOriginal()
 486  
     {
 487  2268
         isOriginal = (mpegBytes[BYTE_4] & MASK_MP3_HOME) != 0;
 488  2268
     }
 489  
 
 490  
     /**
 491  
      * Sets the protected attribute of the MPEGFrame object
 492  
      */
 493  
     private void setProtected()
 494  
     {
 495  2476
         isProtected = (mpegBytes[BYTE_2] & MASK_MP3_PROTECTION) == 0x00;
 496  2476
     }
 497  
 
 498  
     /**
 499  
      * Sets the private attribute of the MPEGFrame object
 500  
      */
 501  
     private void setPrivate()
 502  
     {
 503  2268
         isPrivate = (mpegBytes[BYTE_3] & MASK_MP3_PRIVACY) != 0;
 504  2268
     }
 505  
 
 506  
     /**
 507  
      * Get the setBitrate of this frame
 508  
      * @throws org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
 509  
      */
 510  
     private void setBitrate() throws InvalidAudioFrameException
 511  
     {
 512  
         /* BitRate, get by checking header setBitrate bits and MPEG Version and Layer */
 513  2476
         int bitRateIndex = mpegBytes[BYTE_3] & MASK_MP3_BITRATE | mpegBytes[BYTE_2] & MASK_MP3_ID | mpegBytes[BYTE_2] & MASK_MP3_LAYER;
 514  
 
 515  2476
         bitRate = bitrateMap.get(bitRateIndex);
 516  2476
         if (bitRate == null)
 517  
         {
 518  176
             throw new InvalidAudioFrameException("Invalid bitrate");
 519  
         }
 520  2300
     }
 521  
 
 522  
 
 523  
     /**
 524  
      * Set the Mpeg channel mode of this frame as a constant (see constants)
 525  
      * @throws org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
 526  
      */
 527  
     private void setChannelMode() throws InvalidAudioFrameException
 528  
     {
 529  2268
         channelMode = (mpegBytes[BYTE_4] & MASK_MP3_MODE) >>> 6;
 530  2268
         channelModeAsString = modeMap.get(channelMode);
 531  2268
         if (channelModeAsString == null)
 532  
         {
 533  0
             throw new InvalidAudioFrameException("Invalid channel mode");
 534  
         }
 535  2268
     }
 536  
 
 537  
     /**
 538  
      * Get the setEmphasis mode of this frame in a string representation
 539  
      * @throws org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
 540  
      */
 541  
     private void setEmphasis() throws InvalidAudioFrameException
 542  
     {
 543  2268
         emphasis = mpegBytes[BYTE_4] & MASK_MP3_EMPHASIS;
 544  2268
         emphasisAsString = emphasisMap.get(emphasis);
 545  2268
         if (getEmphasisAsString() == null)
 546  
         {
 547  0
             throw new InvalidAudioFrameException("Invalid emphasis");
 548  
         }
 549  2268
     }
 550  
 
 551  
 
 552  
     /**
 553  
      * Set whether this frame uses padding bytes
 554  
      */
 555  
     private void setPadding()
 556  
     {
 557  2268
         isPadding = (mpegBytes[BYTE_3] & MASK_MP3_PADDING) != 0;
 558  2268
     }
 559  
 
 560  
 
 561  
     /**
 562  
      * Get the layer version of this frame as a constant int value (see constants)
 563  
      * @throws org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
 564  
      */
 565  
     private void setLayer() throws InvalidAudioFrameException
 566  
     {
 567  2481
         layer = (mpegBytes[BYTE_2] & MASK_MP3_LAYER) >>> 1;
 568  2481
         layerAsString = mpegLayerMap.get(layer);
 569  2481
         if (layerAsString == null)
 570  
         {
 571  5
             throw new InvalidAudioFrameException("Invalid Layer");
 572  
         }
 573  2476
     }
 574  
 
 575  
 
 576  
     /**
 577  
      * Sets the string representation of the mode extension of this frame
 578  
      * @throws org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
 579  
      */
 580  
     private void setModeExtension() throws InvalidAudioFrameException
 581  
     {
 582  2268
         int index = (mpegBytes[BYTE_4] & MASK_MP3_MODE_EXTENSION) >> 4;
 583  2268
         if (layer == LAYER_III)
 584  
         {
 585  2133
             modeExtension = modeExtensionLayerIIIMap.get(index);
 586  2133
             if (getModeExtension() == null)
 587  
             {
 588  0
                 throw new InvalidAudioFrameException("Invalid Mode Extension");
 589  
             }
 590  
         }
 591  
         else
 592  
         {
 593  135
             modeExtension = modeExtensionMap.get(index);
 594  135
             if (getModeExtension() == null)
 595  
             {
 596  0
                 throw new InvalidAudioFrameException("Invalid Mode Extension");
 597  
             }
 598  
         }
 599  2268
     }
 600  
 
 601  
     /**
 602  
      * set the sampling rate in Hz of this frame
 603  
      * @throws org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
 604  
      */
 605  
     private void setSamplingRate() throws InvalidAudioFrameException
 606  
     {
 607  
         //Frequency
 608  2300
         int index = (mpegBytes[BYTE_3] & MASK_MP3_FREQUENCY) >>> 2;
 609  2300
         Map<Integer, Integer> samplingRateMapForVersion = samplingRateMap.get(version);
 610  2300
         if (samplingRateMapForVersion == null)
 611  
         {
 612  0
             throw new InvalidAudioFrameException("Invalid version");
 613  
         }
 614  2300
         samplingRate = samplingRateMapForVersion.get(index);
 615  2300
         if (samplingRate == null)
 616  
         {
 617  32
             throw new InvalidAudioFrameException("Invalid sampling rate");
 618  
         }
 619  2268
     }
 620  
 
 621  
     /**
 622  
      * Gets the number of channels
 623  
      *
 624  
      * @return The setChannelMode value
 625  
      */
 626  
     public int getNumberOfChannels()
 627  
     {
 628  64
         switch (channelMode)
 629  
         {
 630  
             case MODE_DUAL_CHANNEL:
 631  0
                 return 2;
 632  
             case MODE_JOINT_STEREO:
 633  12
                 return 2;
 634  
             case MODE_MONO:
 635  52
                 return 1;
 636  
             case MODE_STEREO:
 637  0
                 return 2;
 638  
             default:
 639  0
                 return 0;
 640  
         }
 641  
     }
 642  
 
 643  
     public int getChannelMode()
 644  
     {
 645  2428
         return channelMode;
 646  
     }
 647  
 
 648  
     public String getChannelModeAsString()
 649  
     {
 650  55
         return channelModeAsString;
 651  
     }
 652  
 
 653  
     /**
 654  
      * Gets the mPEGVersion attribute of the MPEGFrame object
 655  
      *
 656  
      * @return The mPEGVersion value
 657  
      */
 658  
     public int getVersion()
 659  
     {
 660  6344
         return version;
 661  
     }
 662  
 
 663  
     public String getVersionAsString()
 664  
     {
 665  55
         return versionAsString;
 666  
     }
 667  
 
 668  
     /**
 669  
      * Gets the paddingLength attribute of the MPEGFrame object
 670  
      *
 671  
      * @return The paddingLength value
 672  
      */
 673  
     public int getPaddingLength()
 674  
     {
 675  2784
         if (isPadding())
 676  
         {
 677  412
             return 1;
 678  
         }
 679  
         else
 680  
         {
 681  2372
             return 0;
 682  
         }
 683  
     }
 684  
 
 685  
     public Integer getBitRate()
 686  
     {
 687  4840
         return bitRate;
 688  
     }
 689  
 
 690  
     public Integer getSamplingRate()
 691  
     {
 692  4929
         return samplingRate;
 693  
     }
 694  
 
 695  
     /*
 696  
      * Gets this frame length in bytes, value should always be rounded down to the nearest byte (not rounded up)
 697  
      *
 698  
      * Calculation is Bitrate (scaled to bps) divided by sampling frequency (in Hz), The larger the bitrate the larger
 699  
      * the frame but the more samples per second the smaller the value, also have to take into account frame padding
 700  
      * Have to multiple by a coefficient constant depending upon the layer it is encoded in,
 701  
 
 702  
      */
 703  
     public int getFrameLength()
 704  
     {
 705  2784
         switch (version)
 706  
         {
 707  
             case VERSION_2:
 708  
             case VERSION_2_5:
 709  254
                 switch (layer)
 710  
                 {
 711  
                     case LAYER_I:
 712  28
                         return (LAYER_I_FRAME_SIZE_COEFFICIENT * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength()) * LAYER_I_SLOT_SIZE;
 713  
 
 714  
                     case LAYER_II:
 715  36
                         if (this.getChannelMode() == MODE_MONO)
 716  
                         {
 717  0
                             return (LAYER_II_FRAME_SIZE_COEFFICIENT / 2) * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength() * LAYER_II_SLOT_SIZE;
 718  
                         }
 719  
                         else
 720  
                         {
 721  36
                             return (LAYER_II_FRAME_SIZE_COEFFICIENT) * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength() * LAYER_II_SLOT_SIZE;
 722  
                         }
 723  
 
 724  
                     case LAYER_III:
 725  190
                         if (this.getChannelMode() == MODE_MONO)
 726  
                         {
 727  186
                             return (LAYER_III_FRAME_SIZE_COEFFICIENT / 2) * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength() * LAYER_III_SLOT_SIZE;
 728  
                         }
 729  
                         else
 730  
                         {
 731  4
                             return (LAYER_III_FRAME_SIZE_COEFFICIENT) * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength() * LAYER_III_SLOT_SIZE;
 732  
                         }
 733  
 
 734  
 
 735  
                     default:
 736  0
                         throw new RuntimeException("Mp3 Unknown Layer:" + layer);
 737  
 
 738  
                 }
 739  
 
 740  
 
 741  
             case VERSION_1:
 742  2530
                 switch (layer)
 743  
                 {
 744  
                     case LAYER_I:
 745  237
                         return (LAYER_I_FRAME_SIZE_COEFFICIENT * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength()) * LAYER_I_SLOT_SIZE;
 746  
 
 747  
                     case LAYER_II:
 748  120
                         return LAYER_II_FRAME_SIZE_COEFFICIENT * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength() * LAYER_II_SLOT_SIZE;
 749  
 
 750  
                     case LAYER_III:
 751  2173
                         return LAYER_III_FRAME_SIZE_COEFFICIENT * (getBitRate() * SCALE_BY_THOUSAND) / getSamplingRate() + getPaddingLength() * LAYER_III_SLOT_SIZE;
 752  
 
 753  
                     default:
 754  0
                         throw new RuntimeException("Mp3 Unknown Layer:" + layer);
 755  
 
 756  
                 }
 757  
 
 758  
             default:
 759  0
                 throw new RuntimeException("Mp3 Unknown Version:" + version);
 760  
 
 761  
         }
 762  
     }
 763  
 
 764  
     /**
 765  
      * 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
 766  
      * and Layer
 767  
      * @return
 768  
      */
 769  
     public int getNoOfSamples()
 770  
     {
 771  2188
         Integer noOfSamples = samplesPerFrameMap.get(version).get(layer);
 772  2188
         return noOfSamples;
 773  
     }
 774  
 
 775  
 
 776  
     public boolean isPadding()
 777  
     {
 778  2784
         return isPadding;
 779  
     }
 780  
 
 781  
     public boolean isCopyrighted()
 782  
     {
 783  52
         return isCopyrighted;
 784  
     }
 785  
 
 786  
     public boolean isOriginal()
 787  
     {
 788  52
         return isOriginal;
 789  
     }
 790  
 
 791  
     public boolean isProtected()
 792  
     {
 793  52
         return isProtected;
 794  
     }
 795  
 
 796  
     public boolean isPrivate()
 797  
     {
 798  52
         return isPrivate;
 799  
     }
 800  
 
 801  
     public boolean isVariableBitRate()
 802  
     {
 803  111
         return false;
 804  
     }
 805  
 
 806  
     public int getEmphasis()
 807  
     {
 808  0
         return emphasis;
 809  
     }
 810  
 
 811  
     public String getEmphasisAsString()
 812  
     {
 813  2268
         return emphasisAsString;
 814  
     }
 815  
 
 816  
     public String getModeExtension()
 817  
     {
 818  2268
         return modeExtension;
 819  
     }
 820  
 
 821  
 
 822  
     /**
 823  
      * Hide Constructor
 824  
      * @throws org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
 825  
      */
 826  
     private MPEGFrameHeader() throws InvalidAudioFrameException
 827  0
     {
 828  
 
 829  0
     }
 830  
 
 831  
     /**
 832  
      * Try and create a new MPEG frame with the given byte array and decodes its contents
 833  
      * If decoding header causes a problem it is not a valid header
 834  
      *
 835  
      * @param b the array of bytes representing this mpeg frame
 836  
      * @throws InvalidAudioFrameException if does not match expected format
 837  
      */
 838  
     private MPEGFrameHeader(byte[] b) throws InvalidAudioFrameException
 839  2481
     {
 840  2481
         mpegBytes = b;
 841  2481
         setVersion();
 842  2481
         setLayer();
 843  2476
         setProtected();
 844  2476
         setBitrate();
 845  2300
         setSamplingRate();
 846  2268
         setPadding();
 847  2268
         setPrivate();
 848  2268
         setChannelMode();
 849  2268
         setModeExtension();
 850  2268
         setCopyrighted();
 851  2268
         setOriginal();
 852  2268
         setEmphasis();
 853  2268
     }
 854  
 
 855  
     /**
 856  
      * Parse the MPEGFrameHeader of an MP3File, file pointer returns at end of the frame header
 857  
      *
 858  
      * @param bb the byte buffer containing the header
 859  
      * @return
 860  
      * @throws InvalidAudioFrameException if there is no header at this point
 861  
      */
 862  
     public static MPEGFrameHeader parseMPEGHeader(ByteBuffer bb) throws InvalidAudioFrameException
 863  
     {
 864  2481
         int position = bb.position();
 865  2481
         bb.get(header, 0, HEADER_SIZE);
 866  2481
         bb.position(position);
 867  2481
         MPEGFrameHeader frameHeader = new MPEGFrameHeader(header);
 868  
 
 869  2268
         return frameHeader;
 870  
     }
 871  
 
 872  
     /**
 873  
      * Gets the MPEGFrame attribute of the MPEGFrame object
 874  
      *
 875  
      * @param bb
 876  
      * @return The mPEGFrame value
 877  
      */
 878  
     public static boolean isMPEGFrame(ByteBuffer bb)
 879  
     {
 880  309872
         int position = bb.position();
 881  309872
         return (((bb.get(position) & SYNC_BYTE1) == SYNC_BYTE1) && ((bb.get(position + 1) & SYNC_BYTE2) == SYNC_BYTE2));
 882  
 
 883  
     }
 884  
 
 885  
     /**
 886  
      * @return a string represntation
 887  
      */
 888  
     public String toString()
 889  
     {
 890  95
         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]);
 891  
     }
 892  
 }
 893