예제 #1
0
        /// <summary>
        /// Parses the audio output mode of this frame's audio data.
        /// </summary>
        /// <param name="frameHeader">The 4 byte header for this frame.</param>
        /// <returns>The audio output mode of this frame's audio data.</returns>
        private static Channel ParseChannel(byte[] frameHeader)
        {
            Channel channel;
            int     channelValue = BitTools.MaskBits(frameHeader, 24, 2);

            switch (channelValue)
            {
            case 3:
                channel = Channel.SingleChannel;
                break;

            case 2:
                channel = Channel.DualChannel;
                break;

            case 1:
                channel = Channel.JointStereo;
                break;

            case 0:
                channel = Channel.Stereo;
                break;

            default:
                channel = Channel.SingleChannel;     // ERROR CASE
                break;
            }

            return(channel);
        }
예제 #2
0
        /// <summary>
        /// Parses the version of the MPEG standard this frame header conforms to from the frame header.
        /// </summary>
        /// <param name="frameHeader"> The 4 byte header for this frame. </param>
        /// <returns>
        /// The version of the MPEG standard this frame conforms to.
        /// 1 = Mpeg 1
        /// 2 = Mpeg 2
        /// 3 = Mpeg 2.5
        /// </returns>
        private static int ParseVersion(byte[] frameHeader)
        {
            int version;
            int versionValue = BitTools.MaskBits(frameHeader, 11, 2);

            switch (versionValue)
            {
            case 3:
                version = 1;
                break;

            case 2:
                version = 2;
                break;

            case 0:
                version = 3;
                break;

            default:
                // This indicates an invalid version.
                version = -1;
                break;
            }

            return(version);
        }
예제 #3
0
        /// <summary>
        /// Parses which complexity layer of the MPEG standard this frame conforms to from the frame header.
        /// </summary>
        /// <param name="frameHeader">The 4 byte header for this frame.</param>
        /// <returns>The complexity layer this frame conforms to.</returns>
        private static int ParseLayer(byte[] frameHeader)
        {
            int layer;
            int layerValue = BitTools.MaskBits(frameHeader, 13, 2);

            switch (layerValue)
            {
            case 3:
                layer = 1;
                break;

            case 2:
                layer = 2;
                break;

            case 1:
                layer = 3;
                break;

            default:
                // This indicates an invalid layer.
                layer = -1;
                break;
            }

            return(layer);
        }
예제 #4
0
        /// <summary>
        /// Quickly checks an array of bytes to see if it represents a valid AAC frame header.
        /// </summary>
        /// <param name="frameHeader">Bytes representing an AAC frame header.</param>
        /// <returns>true if the supplied bytes are a valid frame header, otherwise, false.</returns>
        public static bool IsValidFrame(byte[] frameHeader)
        {
            if (frameHeader == null)
            {
                throw new ArgumentNullException("frameHeader");
            }

            int value = BitTools.MaskBits(frameHeader, 0, 12);

            if (value != AacpFrame.syncValue)
            {
                return(false);
            }

            int sampleRate = AacpFrame.ParseSampleRate(frameHeader);

            if (sampleRate == -1)
            {
                return(false);
            }

            int numberOfChannels = AacpFrame.ParseChannel(frameHeader);

            if (numberOfChannels == -1)
            {
                return(false);
            }

            return(true);
        }
예제 #5
0
        /// <summary>
        /// Quickly checks an array of bytes to see if it represents a valid MP3 frame header.
        /// </summary>
        /// <param name="frameHeader">Bytes representing an MP3 frame header.</param>
        /// <returns>true if the supplied bytes are a valid frame header, otherwise, false.</returns>
        public static bool IsValidFrame(byte[] frameHeader)
        {
            if (frameHeader == null)
            {
                throw new ArgumentNullException("frameHeader");
            }

            if (frameHeader.Length != 4)
            {
                throw new ArgumentException("frameHeader must be of length 4.");
            }

            int value = BitTools.MaskBits(frameHeader, 0, 11);

            if (value != SyncValue)
            {
                return(false);
            }

            int version           = ParseVersion(frameHeader);
            int layer             = ParseLayer(frameHeader);
            int bitrateIndex      = BitTools.MaskBits(frameHeader, 16, 4);
            int samplingRateIndex = BitTools.MaskBits(frameHeader, 20, 2);

            if ((version == -1) || (layer == -1) ||
                (bitrateIndex < 0) || (bitrateIndex >= 15) ||
                (samplingRateIndex < 0) || (samplingRateIndex >= 3))
            {
                return(false);
            }

            return(true);
        }
예제 #6
0
        /// <summary>
        /// Parses the sample rate from the supplied AAC frame header.
        /// </summary>
        /// <param name="frameHeader">Byte array containing the AAC frame header.</param>
        /// <returns>The sample rate of the supplied AAC frame header.</returns>
        private static int ParseSampleRate(byte[] frameHeader)
        {
            int sampleRateValue = BitTools.MaskBits(frameHeader, 18, 4);

            if ((sampleRateValue < 0) || (sampleRateValue > 15))
            {
                return(-1);
            }

            return(AacpFrame.sampleRateTable[sampleRateValue]);
        }
예제 #7
0
        /// <summary>
        /// Parses the number of channels from the supplied AAC frame header.
        /// </summary>
        /// <param name="frameHeader">Byte array containing the AAC frame header.</param>
        /// <returns>The number of channels of the supplied AAC frame header.</returns>
        private static int ParseChannel(byte[] frameHeader)
        {
            int channelValue = BitTools.MaskBits(frameHeader, 23, 3);

            if ((channelValue < 1) || (channelValue > 7))
            {
                // Invalid or reserved channel value
                return(-1);
            }

            return(AacpFrame.numberOfChannelsTable[channelValue]);
        }
예제 #8
0
        /// <summary>
        /// Initializes a new instance of the MpegFrame class.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This class is a partial implementation of an MPEG audio frame.  The primary purpose of this class is to represent an Mpeg 1 Layer 3
        /// file or MP3 file for short. Many of the features not explicitly needed
        /// for audio rendering are omitted from the implementation.
        /// </para>
        /// <para>
        /// Data on this format is readily discoverable in many books as well as by
        /// searching for "MP3 Frame" in your favorite search engine. As always,
        /// Wikipedia is well stocked in all of these areas as well.
        /// </para>
        /// </remarks>
        /// <param name="frameHeader">Byte array containing 4 bytes representing an MPEG Layer 3 header.</param>
        public MpegFrame(byte[] frameHeader)
        {
            if (frameHeader == null)
            {
                throw new ArgumentNullException("frameHeader");
            }

            if (frameHeader.Length != 4)
            {
                throw new ArgumentException("Invalid frame header length.");
            }

            // Sync
            int value = BitTools.MaskBits(frameHeader, 0, 11);

            if (value != SyncValue)
            {
                throw new ArgumentException("Invalid sync value.");
            }

            this.Version           = ParseVersion(frameHeader);
            this.Layer             = ParseLayer(frameHeader);
            this.IsProtected       = BitTools.MaskBits(frameHeader, 15, 1) == 1 ? false : true;
            this.BitrateIndex      = BitTools.MaskBits(frameHeader, 16, 4);
            this.SamplingRateIndex = BitTools.MaskBits(frameHeader, 20, 2);
            this.Padding           = BitTools.MaskBits(frameHeader, 22, 1);
            //// Private Bit = BitTools.MaskBits(_mp3FrameHeader,8,1); //USELESS
            this.Channels = ParseChannel(frameHeader);
            //// Joint Mode = ParseJoitMode(_mp3FrameHeader); //Not used by  Mp3MSS
            //// CopyRight = BitTools.MaskBits(_mp3FrameHeader,3,1); //Not used by Mp3MSS
            //// Original = BitTools.MaskBits(_mp3FrameHeader,2,1); //Not used by Mp3MSS
            //// Emphasis = ParseEmphasis(_mp3FrameHeader); //Not used by Mp3MSS

            this.BitRate          = MpegFrame.CalculateBitRate(this.Version, this.Layer, this.BitrateIndex);
            this.SamplingRate     = MpegFrame.LookupSamplingRate(this.Version, this.SamplingRateIndex);
            this.FrameSize        = MpegFrame.CalculateFrameSize(this.Version, this.Layer, this.BitRate, this.SamplingRate, this.Padding);
            this.NumberOfChannels = (this.Channels == Channel.SingleChannel) ? 1 : 2;

            if ((this.Version == -1) || (this.Layer == -1) ||
                (this.BitrateIndex < 0) || (this.BitrateIndex >= 15) ||
                (this.SamplingRateIndex < 0) || (this.SamplingRateIndex >= 3))
            {
                throw new ArgumentException("Invalid header values");
            }

            // Add in the bytes we already read
            if (this.FrameSize <= 0)
            {
                throw new InvalidOperationException("MpegFrame's FrameSize must be greater than zero.");
            }
        }
예제 #9
0
        /// <summary>
        /// Initializes a new instance of the AacpFrame class.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This class is a partial implementation of an AAC audio frame.  The primary purpose of this class is to represent an AAC
        /// file. Many of the features not explicitly needed for audio rendering are omitted from the implementation.
        /// </para>
        /// <para>
        /// Data on this format is readily discoverable in many books as well as by
        /// searching for "AAC Frame" in your favorite search engine. As always,
        /// Wikipedia is well stocked in all of these areas as well.
        /// </para>
        /// </remarks>
        /// <param name="frameHeader">Byte array containing 4 bytes representing an AAC header.</param>
        public AacpFrame(byte[] frameHeader)
            : base()
        {
            if (frameHeader == null)
            {
                throw new ArgumentNullException("frameHeader");
            }

            // Sync
            int value = BitTools.MaskBits(frameHeader, 0, 12);

            if (value != syncValue)
            {
                throw new ArgumentException("Invalid sync value.");
            }

            this.NumberOfChannels = AacpFrame.ParseChannel(frameHeader);
            this.SamplingRate     = AacpFrame.ParseSampleRate(frameHeader);
            this.BitRate          = AacpFrame.CalculateBitRate(this.SamplingRate, this.NumberOfChannels);
            this.FrameSize        = AacpFrame.ParseFrameSize(frameHeader);

            int objectTypeId = BitTools.MaskBits(frameHeader, 16, 2);
        }
예제 #10
0
        /// <summary>
        /// Parses the AAC frame header to find the actual size of the header.
        /// </summary>
        /// <param name="frameHeader">Byte array containing the AAC frame header.</param>
        /// <returns>Actual size of the supplied AAC frame header.</returns>
        private static int ParseFrameSize(byte[] frameHeader)
        {
            int value = BitTools.MaskBits(frameHeader, 30, 13);

            return(value);
        }