示例#1
0
        /// <summary>
        /// Returns the calculated frame length (including header
        /// and CRC)
        /// </summary>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException">
        /// CanCalculateFrameLength is false
        /// </exception>
        public static int CalculateFrameLength(Mp3FrameHeader fh)
        {
            if (null == fh)
            {
                throw new ArgumentNullException("fh");
            }
            if (fh.Version == MpegVersion.Reserved)
            {
                throw new InvalidOperationException("This frame has a reserved version");
            }

            int scaleFactor;
            int slotSize;

            switch (fh.Layer)
            {
                case MpegLayer.Layer1:
                    scaleFactor = L1_SCALE;
                    slotSize = L1_SLOTSIZE;
                    break;
                case MpegLayer.Layer2:
                case MpegLayer.Layer3:
                    scaleFactor = L23_SCALE;
                    slotSize = L23_SLOTSIZE;
                    break;
                case MpegLayer.Reserved:
                    throw new InvalidOperationException("This frame has a reserved layer");
                default:
                    Debug.Fail(UnexpectedException.Message);
                    throw new UnexpectedException();
            }

            try
            {
                int paddingSlots = fh.HasPadding ? 1 : 0;
                int crcSize = fh.HasCRC ? Mp3Frame.CRC_SIZE : 0;
                int numSlots = scaleFactor * CalculateBitrate(fh) / CalculateSamplerate(fh) + paddingSlots;
                int dataSize = numSlots * slotSize;
                return dataSize + crcSize;
            }
            catch (InvalidOperationException e)
            {
                // I know this is brittle. Fortunately I've got unit test power
                if (e.Message.Contains("bitrate"))
                {
                    throw new InvalidOperationException("Cannot calculate bitrate");
                }
                else
                {
                    throw new InvalidOperationException("Cannot calculate samplerate");
                }
            }
            catch
            {
                Debug.Fail(UnexpectedException.Message);
                throw new UnexpectedException();
            }
        }
示例#2
0
        /// <summary>
        /// Bitrate
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Bitrate is free or invalid, or the version or layer is reserved
        /// </exception>
        public static int CalculateBitrate(Mp3FrameHeader fh)
        {
            if (null == fh)
            {
                throw new ArgumentNullException("fh");
            }
            if (fh.HasFreeBitrate)
            {
                throw new InvalidOperationException("This frame has a free bitrate");
            }
            if (fh.HasInvalidBitrate)
            {
                throw new InvalidOperationException("This frame has an invalid bitrate");
            }

            return BITRATE_TABLE[GetBitrateTableIndex(fh), fh.BitrateIndex];
        }
示例#3
0
 public void CalculateBitrate_HasFreeTest()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_BR_FREE]);
     Mp3FrameHeaderRules.CalculateBitrate(h);
 }
示例#4
0
        /// <summary>
        /// True if this represents a valid MPEG frame
        /// </summary>
        /// <remarks>
        /// This does not indicate a valid MP3 frame
        /// </remarks>
        public static bool IsValid(Mp3FrameHeader fh)
        {
            if (null == fh)
            {
                throw new ArgumentNullException("fh");
            }
            bool isInvalid =
                   !fh.HasFrameSync
                || fh.Version == MpegVersion.Reserved
                || fh.Layer == MpegLayer.Reserved
                || fh.HasInvalidBitrate
                || fh.HasReservedSamplerate
                || fh.Emphasis == MpegEmphasis.Reserved
                || HasInvalidBitrateForChannelMode(fh);

            return !isInvalid;
        }
示例#5
0
 /// <summary>
 /// The samplerate for this frame is known, if the
 /// sample rate is not reserved and the mpeg version is not reserved
 /// </summary>
 public static bool CanCalculateSamplerate(Mp3FrameHeader fh)
 {
     if (null == fh)
     {
         throw new ArgumentNullException("fh");
     }
     return !(fh.HasReservedSamplerate || fh.Version == MpegVersion.Reserved);
 }
示例#6
0
 /// <summary>
 /// If a bitrate can be calculated from the frame header
 /// (i.e. if CalculateBitrate won't throw)
 /// </summary>
 public static bool CanCalculateBitrate(Mp3FrameHeader fh)
 {
     if (null == fh)
     {
         throw new ArgumentNullException("fh");
     }
     return !(
            fh.HasFreeBitrate
         || fh.HasInvalidBitrate
         || fh.Version == MpegVersion.Reserved
         || fh.Layer == MpegLayer.Reserved);
 }
示例#7
0
 public static int CalculatePayloadLength(Mp3FrameHeader fh)
 {
     return CalculateFrameLength(fh)
         - Mp3FrameHeader.HEADER_SIZE
         - (fh.HasCRC ? Mp3Frame.CRC_SIZE : 0);
 }
示例#8
0
 public void HasInvalidBitrateForChannelMode_Test()
 {
     h = new Mp3FrameHeader(TEST_HEADER[0]);
     Assert.That(Mp3FrameHeaderRules.HasInvalidBitrateForChannelMode(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[1]);
     Assert.That(Mp3FrameHeaderRules.HasInvalidBitrateForChannelMode(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[2]);
     Assert.That(Mp3FrameHeaderRules.HasInvalidBitrateForChannelMode(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[3]);
     Assert.That(Mp3FrameHeaderRules.HasInvalidBitrateForChannelMode(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[4]);
     Assert.That(Mp3FrameHeaderRules.HasInvalidBitrateForChannelMode(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[5]);
     Assert.That(Mp3FrameHeaderRules.HasInvalidBitrateForChannelMode(h), Is.True);
 }
示例#9
0
 public void CalculateFrameLength_ReservedVersionTest()
 {
     h = new Mp3FrameHeader(TEST_HEADER[3]);
     Mp3FrameHeaderRules.CalculateFrameLength(h);
 }
示例#10
0
 public void CalculateFrameLength_ReservedLayerTest()
 {
     h = new Mp3FrameHeader(TEST_HEADER[4]);
     Mp3FrameHeaderRules.CalculateFrameLength(h);
 }
示例#11
0
 public void CalculateFrameLength_NoSamplerateTest()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_SR_RESERVED]);
     Mp3FrameHeaderRules.CalculateFrameLength(h);
 }
示例#12
0
 public void CalculateFrameLength_NoBitrateTest()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_BR_FREE]);
     Mp3FrameHeaderRules.CalculateFrameLength(h);
 }
示例#13
0
 public void CalculateBitrate_Test()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_BR_128]);
     Assert.That(Mp3FrameHeaderRules.CalculateBitrate(h), Is.EqualTo(128000));
 }
示例#14
0
 public void CalculateBitrate_ReservedLayerTest()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_BR_LR]);
     Mp3FrameHeaderRules.CalculateBitrate(h);
 }
示例#15
0
 public void CalculateBitrate_HasInvalidTest()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_BR_INVALID]);
     Mp3FrameHeaderRules.CalculateBitrate(h);
 }
示例#16
0
 public void CanCalculateFrameLength_Test()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_OK]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateFrameLength(h), Is.True);
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_LR]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateFrameLength(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_BR_INVALID]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateFrameLength(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_BR_FREE]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateFrameLength(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_SR_RESERVED]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateFrameLength(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_VR]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateFrameLength(h), Is.False);
 }
示例#17
0
 public void CanCalculateSamplerate_Test()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_SR_RESERVED]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateSamplerate(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_BR_VR]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateSamplerate(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_SMOKE]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateSamplerate(h), Is.True);
 }
示例#18
0
 public void CalculateFrameLength_Test()
 {
     // V25, Layer 1, no padding
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_V25L1_NO_PADDING]);
     Assert.That(Mp3FrameHeaderRules.CalculateFrameLength(h), Is.EqualTo(624));
     // V25, Layer 1, padding
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_V25L1_PADDING]);
     Assert.That(Mp3FrameHeaderRules.CalculateFrameLength(h), Is.EqualTo(132));
     // V2, Layer 2, no padding
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_V2L2_NO_PADDING]);
     Assert.That(Mp3FrameHeaderRules.CalculateFrameLength(h), Is.EqualTo(1296));
     // V2, Layer 2, padding
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_V2L2_PADDING]);
     Assert.That(Mp3FrameHeaderRules.CalculateFrameLength(h), Is.EqualTo(145));
     // V1, Layer 3, no padding
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_V1L3_NO_PADDING]);
     Assert.AreEqual(112000, Mp3FrameHeaderRules.CalculateBitrate(h));
     Assert.AreEqual(32000, Mp3FrameHeaderRules.CalculateSamplerate(h));
     Assert.That(Mp3FrameHeaderRules.CalculateFrameLength(h), Is.EqualTo(504));
     // V1, Layer 3, padding
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_V1L3_PADDING]);
     Assert.That(Mp3FrameHeaderRules.CalculateFrameLength(h), Is.EqualTo(169));
     // Add a CRC
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_WITH_CRC]);
     Assert.That(Mp3FrameHeaderRules.CalculateFrameLength(h), Is.EqualTo(171));
 }
示例#19
0
 public void IsValid_Test()
 {
     h = new Mp3FrameHeader(TEST_HEADER[0]);
     Assert.That(Mp3FrameHeaderRules.IsValid(h), Is.True);
     h = new Mp3FrameHeader(TEST_HEADER[1]);
     Assert.That(Mp3FrameHeaderRules.IsValid(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[2]);
     Assert.That(Mp3FrameHeaderRules.IsValid(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[3]);
     Assert.That(Mp3FrameHeaderRules.IsValid(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[4]);
     Assert.That(Mp3FrameHeaderRules.IsValid(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[5]);
     Assert.That(Mp3FrameHeaderRules.IsValid(h), Is.False);
 }
示例#20
0
 public void CalculatePayloadLength_CantCalculateTest()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_BR_FREE]);
     Mp3FrameHeaderRules.CalculatePayloadLength(h);
 }
示例#21
0
 /// <summary>
 /// Get the samplerate
 /// </summary>
 /// <exception cref="InvalidOperationException">
 /// HasReservedSamplerate is true or mpeg version is reserved
 /// </exception>
 public static int CalculateSamplerate(Mp3FrameHeader fh)
 {
     if (null == fh)
     {
         throw new ArgumentNullException("fh");
     }
     if (fh.HasReservedSamplerate)
     {
         throw new InvalidOperationException("This frame has a reserved samplerate");
     }
     if (fh.Version == MpegVersion.Reserved)
     {
         throw new InvalidOperationException("This frame has a reserved version");
     }
     switch (fh.Version)
     {
         case MpegVersion.V1:
             return SAMPLERATE_TABLE[SRIDX_V1, fh.SamplerateIndex];
         case MpegVersion.V2:
             return SAMPLERATE_TABLE[SRIDX_V2, fh.SamplerateIndex];
         case MpegVersion.V25:
             return SAMPLERATE_TABLE[SRIDX_V25, fh.SamplerateIndex];
         default:
             Debug.Fail(UnexpectedException.Message);
             throw new UnexpectedException();
     }
 }
示例#22
0
 public void CalculatePayloadLength_Test()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_V1L3_PADDING]);
     Assert.That(Mp3FrameHeaderRules.CalculatePayloadLength(h), Is.EqualTo(169 - 4));
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_LEN_WITH_CRC]);
     Assert.That(Mp3FrameHeaderRules.CalculatePayloadLength(h), Is.EqualTo(171 - 6));
 }
示例#23
0
 /// <summary>
 /// The frame length can be calculated
 /// </summary>
 /// <remarks> The frame length depends on the bitrate,
 /// samplerate, and layer.
 /// 
 /// Header is invalid if false</remarks>
 /// <returns></returns>
 public static bool CanCalculateFrameLength(Mp3FrameHeader fh)
 {
     // Layer is also needed in the calculation, but
     // that's taken into account by CanCalculateBitrate
     return CanCalculateBitrate(fh) && CanCalculateSamplerate(fh);
 }
示例#24
0
 public void CalculateSamplerate_HasReservedTest()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_SR_RESERVED]);
     Mp3FrameHeaderRules.CalculateSamplerate(h);
 }
示例#25
0
        /// <summary>
        /// Determines if the header claims a valid
        /// combination of bitrate and channel mode
        /// </summary>
        /// <remarks>
        /// Frame is invalid if true
        /// </remarks>
        public static bool HasInvalidBitrateForChannelMode(Mp3FrameHeader fh)
        {
            if (null == fh)
            {
                throw new ArgumentNullException("fh");
            }
            if (fh.Layer != MpegLayer.Layer2)
            {
                return false;
            }
            if (fh.HasFreeBitrate || fh.HasInvalidBitrate)
            {
                return false;
            }

            switch (CalculateBitrate(fh))
            {
                case 32000:
                case 48000:
                case 56000:
                case 80000:
                    if (fh.ChannelMode == MpegChannelMode.SingleChannel)
                    {
                        return false;
                    }
                    else
                    {
                        return true;
                    }
                case 224000:
                case 256000:
                case 320000:
                case 384000:
                    if (fh.ChannelMode != MpegChannelMode.SingleChannel)
                    {
                        return false;
                    }
                    else
                    {
                        return true;
                    }
                default:
                    return false;
            }
        }
示例#26
0
 public void CalculateSamplerate_ReservedVersionTest()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_BR_VR]);
     Mp3FrameHeaderRules.CalculateSamplerate(h);
 }
示例#27
0
 private static int GetBitrateTableIndex(Mp3FrameHeader fh)
 {
     // This is gorgeous
     // Could also be done using more tables
     switch (fh.Version)
     {
         case MpegVersion.V1:
             switch (fh.Layer)
             {
                 case MpegLayer.Layer1:
                     return BRIDX_V1L1;
                 case MpegLayer.Layer2:
                     return BRIDX_V1L2;
                 case MpegLayer.Layer3:
                     return BRIDX_V1L3;
                 case MpegLayer.Reserved:
                     break;
                 default:
                     Debug.Fail(UnexpectedException.Message);
                     throw new UnexpectedException();
             }
             break;
         case MpegVersion.V2:
         case MpegVersion.V25:
             switch (fh.Layer)
             {
                 case MpegLayer.Layer1:
                     return BRIDX_V2L1;
                 case MpegLayer.Layer2:
                     return BRIDX_V2L2;
                 case MpegLayer.Layer3:
                     return BRIDX_V2L3;
                 case MpegLayer.Reserved:
                     break;
                 default:
                     Debug.Fail(UnexpectedException.Message);
                     throw new UnexpectedException();
             }
             break;
         case MpegVersion.Reserved:
             throw new InvalidOperationException("This frame does not specify a version");
         default:
             Debug.Fail(UnexpectedException.Message);
             throw new UnexpectedException();
     }
     throw new InvalidOperationException("This frame does not specify a layer");
 }
示例#28
0
 public void CalculateSamplerate_Test()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_SMOKE]);
     Assert.That(Mp3FrameHeaderRules.CalculateSamplerate(h), Is.EqualTo(44100));
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_SR00_V25]);
     Assert.That(Mp3FrameHeaderRules.CalculateSamplerate(h), Is.EqualTo(11025));
 }
示例#29
0
 public void CanCalculateBitrate_Test()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_BR_128]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateBitrate(h), Is.True);
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_BR_FREE]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateBitrate(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_BR_INVALID]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateBitrate(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_BR_VR]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateBitrate(h), Is.False);
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_BR_LR]);
     Assert.That(Mp3FrameHeaderRules.CanCalculateBitrate(h), Is.False);
 }
示例#30
0
 public void ChannelMode_Test()
 {
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_CM_STEREO]);
     Assert.That(h.ChannelMode, Is.EqualTo(MpegChannelMode.Stereo));
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_CM_JS]);
     Assert.That(h.ChannelMode, Is.EqualTo(MpegChannelMode.JointStereo));
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_CM_DUAL]);
     Assert.That(h.ChannelMode, Is.EqualTo(MpegChannelMode.DualChannel));
     h = new Mp3FrameHeader(TEST_HEADER[THIDX_CM_MONO]);
     Assert.That(h.ChannelMode, Is.EqualTo(MpegChannelMode.SingleChannel));
 }