public static int XingHeaderOffset(MpegVersion version, MpegChannelMode channelMode)
 {
     if (version == MpegVersion.One)
     {
         if (channelMode == MpegChannelMode.SingleChannel)
         {
             return(0x15);
         }
         else
         {
             return(0x24);
         }
     }
     else
     {
         if (channelMode == MpegChannelMode.SingleChannel)
         {
             return(0x0D);
         }
         else
         {
             return(0x15);
         }
     }
 }
Esempio n. 2
0
 public Granule()
 {
     IsUsed       = false;
     Version      = 0;
     Uncompressed = new UncompressedSampleFrame();
     ChannelInfo  = new List <ChannelInfo>();
 }
Esempio n. 3
0
 static int CalculateSideInfoLength(MpegVersion mpegVersion, int channels)
 {
     if (channels == 1)
     {
         return(mpegVersion == MpegVersion.One ? 17 : 9);
     }
     return(mpegVersion == MpegVersion.One ? 32 : 17);
 }
Esempio n. 4
0
        static int ParseSampleRate(ReadOnlySpan <byte> data, MpegVersion mpegVersion)
        {
            var column = (data[2] >> 2) & 0b00000011;

            if (column == 0b00000011)
            {
                throw new AudioInvalidException("Not a valid MPEG header.");
            }

            return(_sampleRateTable[
Esempio n. 5
0
        static int ParseBitRate(ReadOnlySpan <byte> data, MpegVersion mpegVersion)
        {
            var column = (data[2] >> 4) & 0b00001111;

            if (column == 0b00001111)
            {
                throw new AudioInvalidException("Not a valid MPEG header.");
            }

            return(_bitRateTable[mpegVersion == MpegVersion.One ? 0 : 1, column]);
        }
Esempio n. 6
0
 public void AddFrame(
     MpegVersion version,
     MpegLayer layer,
     bool hasCRC,
     int frameSizeOffset,
     int frameSize)
 {
     Add(new Mp3Frame(BuildFrame(
         version,
         layer,
         hasCRC,
         frameSizeOffset,
         frameSize)));
 }
 //////////////////////////////////////////////////////////////////////////
 // public methods
 //////////////////////////////////////////////////////////////////////////
 public MpegProperties (MpegFile file, ReadStyle style) : base (style)
 {
    this.file      = file;
    duration       = TimeSpan.Zero;
    //bitrate        = 0;
    //sample_rate    = 0;
    //channels       = 0;
    version        = MpegVersion.One;
    //layer          = 0;
    channel_mode   = MpegChannelMode.Stereo;
    //is_copyrighted = false;
    //is_original    = false;
    
    Read();
 }
        //////////////////////////////////////////////////////////////////////////
        // public methods
        //////////////////////////////////////////////////////////////////////////
        public MpegProperties(MpegFile file, ReadStyle style) : base(style)
        {
            this.file = file;
            duration  = TimeSpan.Zero;
            //bitrate        = 0;
            //sample_rate    = 0;
            //channels       = 0;
            version = MpegVersion.One;
            //layer          = 0;
            channel_mode = MpegChannelMode.Stereo;
            //is_copyrighted = false;
            //is_original    = false;

            Read();
        }
Esempio n. 9
0
        public void AddFreeFrame(
            MpegVersion version,
            MpegLayer layer,
            bool hasCRC,
            int frameSizeOffset,
            int frameSize)
        {
            byte[] buf = BuildFrame(
                version,
                layer,
                hasCRC,
                frameSizeOffset,
                frameSize);

            buf[2] &= 0x0F;

            Add(new Mp3Frame(buf));
        }
Esempio n. 10
0
 private void GetVersion(params bool[] twoBits)
 {
     if (twoBits[0] && twoBits[1])
     {
         this.mpegVersion = MpegVersion.MpegVersion1;
     }
     else if (twoBits[0] && !twoBits[1])
     {
         this.mpegVersion = MpegVersion.MpegVersion2;
     }
     else if (!twoBits[0] && twoBits[1])
     {
         this.mpegVersion = MpegVersion.Reserved;
     }
     else if (!twoBits[0] && !twoBits[1])
     {
         this.mpegVersion = MpegVersion.MpegVersion25;
     }
 }
Esempio n. 11
0
        private static int GetSamplesPerFrame(MpegVersion mpegVersion, MpegLayer mpegLayer)
        {
            int tmpSamplesPerFrame = 0;

            switch (mpegVersion)
            {
            // MPEG-1
            case MpegVersion.Mpeg1:
                if (mpegLayer == MpegLayer.Layer1)
                {
                    tmpSamplesPerFrame = 384;
                }
                else if (mpegLayer == MpegLayer.Layer2 ||
                         mpegLayer == MpegLayer.Layer3)
                {
                    tmpSamplesPerFrame = 1152;
                }
                break;

            // MPEG-2/2.5
            case MpegVersion.Mpeg2:
            case MpegVersion.Mpeg25:
                if (mpegLayer == MpegLayer.Layer1)
                {
                    tmpSamplesPerFrame = 384;
                }
                else if (mpegLayer == MpegLayer.Layer2)
                {
                    tmpSamplesPerFrame = 1152;
                }
                else if (mpegLayer == MpegLayer.Layer3)
                {
                    tmpSamplesPerFrame = 576;
                }
                break;
            } // end switch (ID)

            return(tmpSamplesPerFrame);
        }
Esempio n. 12
0
        private static int?GetFreqency(byte three, MpegVersion version)
        {
            int basevalue = 0;

            if (CompBit(three, 5, 2, false, false))
            {
                basevalue = 11025;
            }
            if (CompBit(three, 5, 2, false, true))
            {
                basevalue = 12000;
            }
            if (CompBit(three, 5, 2, true, false))
            {
                basevalue = 8000;
            }
            if (CompBit(three, 5, 2, true, true))
            {
                basevalue = 0;
            }

            if (basevalue != 0)
            {
                if (version == MpegVersion.MPEG25)
                {
                    return(basevalue);
                }
                if (version == MpegVersion.MPEG2)
                {
                    return(basevalue * 2);
                }
                if (version == MpegVersion.MPEG1)
                {
                    return(basevalue * 4);
                }
            }
            return(null);
        }
Esempio n. 13
0
        private void Parse(ByteVector data)
        {
            if (data.Count < 4 || data[0] != 0xff)
            {
                TagLibDebugger.Debug("Mpeg.Header.Parse() -- First byte did not match MPEG synch.");
                return;
            }

            uint flags = data.ToUInt();

            // Check for the second byte'field part of the MPEG synch

            if ((flags & 0xFFE00000) != 0xFFE00000)
            {
                TagLibDebugger.Debug("Mpeg.Header.Parse() -- Second byte did not match MPEG synch.");
                return;
            }

            // Set the MPEG version
            switch ((flags >> 19) & 0x03)
            {
            case 0: version = MpegVersion.TwoPointFive; break;

            case 2: version = MpegVersion.Two; break;

            case 3: version = MpegVersion.One; break;
            }

            // Set the MPEG layer
            switch ((flags >> 17) & 0x03)
            {
            case 1: layer = 3; break;

            case 2: layer = 2; break;

            case 3: layer = 1; break;
            }

            protectionEnabled = ((flags >> 16) & 1) == 0;

            // Set the bitrate
            int[, ,] bitrates = new int[2, 3, 16] {
                {                                                                                // Version 1
                    { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0 }, // layer 1
                    { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0 },    // layer 2
                    { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 } // layer 3
                },
                {                                                                             // Version 2 or 2.5
                    { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 }, // layer 1
                    { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 },      // layer 2
                    { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }  // layer 3
                }
            };

            int versionIndex = version == MpegVersion.One ? 0 : 1;
            int layerIndex   = layer > 0 ? layer - 1 : 0;

            // The bitrate index is encoded as the first 4 bits of the 3rd byte,
            // index.e. 1111xxxx

            int i = (int)(flags >> 12) & 0x0F;

            bitrate = bitrates[versionIndex, layerIndex, i];

            // Set the sample rate

            int[,] sampleRates = new int[3, 4] {
                { 44100, 48000, 32000, 0 }, // Version 1
                { 22050, 24000, 16000, 0 }, // Version 2
                { 11025, 12000, 8000, 0 } // Version 2.5
            };

            // The sample rate index is encoded as two bits in the 3nd byte,
            // index.e. xxxx11xx
            i = (int)(flags >> 10) & 0x03;

            sampleRate = sampleRates[(int)version, i];

            if (sampleRate == 0)
            {
                TagLibDebugger.Debug("Mpeg.Header.Parse() -- Invalid sample rate.");
                return;
            }

            // The channel mode is encoded as a 2 bit value at the end of the 3nd
            // byte, index.e. xxxxxx11
            channelMode = (MpegChannelMode)((flags >> 16) & 0x3);

            // TODO: Add mode extension for completeness

            isCopyrighted = (flags & 1) == 1;
            isOriginal    = ((flags >> 1) & 1) == 1;

            // Calculate the frame length
            if (layer == 1)
            {
                frameLength = 24000 * 2 * bitrate / sampleRate + (IsPadded ? 1 : 0);
            }
            else
            {
                frameLength = 72000 * bitrate / sampleRate + (IsPadded ? 1 : 0);
            }

            // Now that we're done parsing, set this to be a valid frame.
            isValid = true;
        }
Esempio n. 14
0
        /// <summary>checks if the four bytes represent a valid header,
        /// if they are, will parse the values into local properties
        /// </summary>
        private bool IsValidHeader(byte[] headerBytes)
        {
            if ((headerBytes[0] == 0xFF) && ((headerBytes[1] & 0xE0) == 0xE0))
            {
                // TODO: could do with a bitstream class here
                mpegVersion = (MpegVersion)((headerBytes[1] & 0x18) >> 3);
                if (mpegVersion == MpegVersion.Reserved)
                {
                    //throw new FormatException("Unsupported MPEG Version");
                    return(false);
                }

                layer = (MpegLayer)((headerBytes[1] & 0x06) >> 1);

                if (layer == MpegLayer.Reserved)
                {
                    return(false);
                }
                int layerIndex = this.layer == MpegLayer.Layer1 ? 0 : this.layer == MpegLayer.Layer2 ? 1: 2;
                crcPresent = (headerBytes[1] & 0x01) == 0x00;
                int bitRateIndex = (headerBytes[2] & 0xF0) >> 4;
                if (bitRateIndex == 15)
                {
                    // invalid index
                    return(false);
                }
                int versionIndex = this.mpegVersion == Wave.MpegVersion.Version1 ? 0 : 1;
                this.bitRate = bitRates[versionIndex, layerIndex, bitRateIndex] * 1000;
                if (bitRate == 0)
                {
                    return(false);
                }
                int sampleFrequencyIndex = (headerBytes[2] & 0x0C) >> 2;
                if (sampleFrequencyIndex == 3)
                {
                    return(false);
                }
                if (mpegVersion == MpegVersion.Version1)
                {
                    sampleRate = sampleRatesVersion1[sampleFrequencyIndex];
                }
                else if (mpegVersion == MpegVersion.Version2)
                {
                    sampleRate = sampleRatesVersion2[sampleFrequencyIndex];
                }
                else // mpegVersion == MpegVersion.Version25
                {
                    sampleRate = sampleRatesVersion25[sampleFrequencyIndex];
                }

                bool padding    = (headerBytes[2] & 0x02) == 0x02;
                bool privateBit = (headerBytes[2] & 0x01) == 0x01;
                channelMode = (ChannelMode)((headerBytes[3] & 0xC0) >> 6);
                int  channelExtension = (headerBytes[3] & 0x30) >> 4;
                bool copyright        = (headerBytes[3] & 0x08) == 0x08;
                bool original         = (headerBytes[3] & 0x04) == 0x04;
                int  emphasis         = (headerBytes[3] & 0x03);

                int nPadding = padding ? 1 : 0;

                this.samplesInFrame = samplesPerFrame[versionIndex, layerIndex];
                int coefficient = this.samplesInFrame / 8;
                if (this.layer == MpegLayer.Layer1)
                {
                    this.frameLengthInBytes = (coefficient * bitRate / sampleRate + nPadding) * 4;
                }
                else
                {
                    frameLengthInBytes = (coefficient * bitRate) / sampleRate + nPadding;
                }

                if (this.frameLengthInBytes > MaxFrameLength)
                {
                    return(false);
                }
                return(true);
            }
            return(false);
        }
Esempio n. 15
0
        //////////////////////////////////////////////////////////////////////////
        // private methods
        //////////////////////////////////////////////////////////////////////////

        private void Read()
        {
            // Since we've likely just looked for the ID3v1 tag, start at the end of the
            // file where we're least likely to have to have to move the disk head.

            long last = file.LastFrameOffset;

            if (last < 0)
            {
                TagLibDebugger.Debug("Mpeg.Properties.Read() -- Could not find a valid last MPEG frame in the stream.");
                return;
            }

            file.Seek(last);
            MpegHeader last_header = new MpegHeader(file.ReadBlock(4));

            long first = file.FirstFrameOffset;

            if (first < 0)
            {
                TagLibDebugger.Debug("Mpeg.Properties.Read() -- Could not find a valid first MPEG frame in the stream.");
                return;
            }

            if (!last_header.IsValid)
            {
                long pos = last;

                while (pos > first)
                {
                    pos = file.PreviousFrameOffset(pos);

                    if (pos < 0)
                    {
                        break;
                    }

                    file.Seek(pos);
                    MpegHeader header = new MpegHeader(file.ReadBlock(4));

                    if (header.IsValid)
                    {
                        last_header = header;
                        last        = pos;
                        break;
                    }
                }
            }

            // Now jump back to the front of the file and read what we need from there.

            file.Seek(first);
            MpegHeader first_header = new MpegHeader(file.ReadBlock(4));

            if (!first_header.IsValid || !last_header.IsValid)
            {
                TagLibDebugger.Debug("Mpeg.Properties.Read() -- Page headers were invalid.");
                return;
            }

            // Check for a Xing header that will help us in gathering information about a
            // VBR stream.

            int xing_header_offset = MpegXingHeader.XingHeaderOffset(first_header.Version,
                                                                     first_header.ChannelMode);

            file.Seek(first + xing_header_offset);
            MpegXingHeader xing_header = new MpegXingHeader(file.ReadBlock(16));

            // Read the length and the bitrate from the Xing header.

            if (xing_header.IsValid && first_header.SampleRate > 0 && xing_header.TotalFrames > 0)
            {
                int [] block_size = { 0, 384, 1152, 1152 };

                double time_per_frame = block_size [first_header.Layer];
                time_per_frame = first_header.SampleRate > 0 ? time_per_frame / first_header.SampleRate : 0;
                duration       = new TimeSpan((int)(time_per_frame * xing_header.TotalFrames) * TimeSpan.TicksPerSecond);
                bitrate        = (int)(duration > TimeSpan.Zero ? ((xing_header.TotalSize * 8L) / duration.TotalSeconds) / 1000 : 0);
            }

            // Since there was no valid Xing header found, we hope that we're in a constant
            // bitrate file.

            // TODO: Make this more robust with audio property detection for VBR without a
            // Xing header.

            else if (first_header.FrameLength > 0 && first_header.Bitrate > 0)
            {
                int frames = (int)((last - first) / first_header.FrameLength + 1);

                duration = TimeSpan.FromSeconds((double)(first_header.FrameLength * frames) / (double)(first_header.Bitrate * 125) + 0.5);
                bitrate  = first_header.Bitrate;
            }


            sample_rate    = first_header.SampleRate;
            channels       = first_header.ChannelMode == MpegChannelMode.SingleChannel ? 1 : 2;
            version        = first_header.Version;
            layer          = first_header.Layer;
            channel_mode   = first_header.ChannelMode;
            is_copyrighted = first_header.IsCopyrighted;
            is_original    = first_header.IsOriginal;
        }
Esempio n. 16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Mpeg"/> class.
        /// </summary>
        /// <param name="path">The full path of the file.</param>
        /// <param name="calculateBitrate">if set to <c>true</c> the bitrate will be calculated before the constructor returns.</param>
        public Mpeg(string path, bool calculateBitrate)
        {
            _fileName = path;

            using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                int tmpID3v2TagSize = ID3v2.GetTagSize(stream);
                stream.Seek(tmpID3v2TagSize, SeekOrigin.Begin);

                byte[] tmpFrameHeader = new byte[4];

                bool acceptNullSamples = false;
                while (true)
                {
                    int tmpByte = stream.ReadByte(); // keep as ReadByte
                    while (tmpByte != 0xFF && tmpByte != -1)
                    {
                        tmpByte = stream.ReadByte(); // keep as ReadByte
                    }

                    if (tmpByte == -1)
                    {
                        if (acceptNullSamples)
                        {
                            throw new InvalidDataException(string.Format("'{0}': Can't find frame sync", path));
                        }
                        stream.Seek(tmpID3v2TagSize, SeekOrigin.Begin);
                        acceptNullSamples = true;
                        continue;
                    }

                    tmpFrameHeader[0] = (byte)tmpByte;

                    // Get frame header
                    if (stream.Read(tmpFrameHeader, 1, 3) != 3)
                    {
                        throw new InvalidDataException(string.Format("'{0}': Invalid MPEG file; end of stream reached", path));
                    }

                    // No sync
                    if ((tmpFrameHeader[1] >> 5) != 0x07 ||
                        ((tmpFrameHeader[1] >> 1) & 0x03) == 0) // 2/18/05 - ignore reserved layer
                    {
                        stream.Seek(-3, SeekOrigin.Current);
                    }
                    else if (tmpFrameHeader[1] == 0xFF ||
                            ((tmpFrameHeader[1] >> 3) & 0x03) == 1) // 2/19/05 - more bad data
                    {
                        stream.Seek(-3, SeekOrigin.Current);
                    }
                    else
                    {
                        int tmpMpegID = (tmpFrameHeader[1] >> 3) & 0x03;
                        int tmpLayerNum = (tmpFrameHeader[1] >> 1) & 0x03;
                        int tmpFrequency = GetFrequency((MpegVersion)tmpMpegID, (tmpFrameHeader[2] >> 2) & 0x03);

                        // Check for invalid frequency
                        if (tmpFrequency == 0)
                        {
                            stream.Seek(-3, SeekOrigin.Current);
                            continue;
                        }

                        int tmpSamplesPerFrame = GetSamplesPerFrame((MpegVersion)tmpMpegID, (MpegLayer)tmpLayerNum);

                        int tmpUsesPadding = (tmpFrameHeader[2] >> 1) & 0x01;
                        double tmpFrameSizeConst = 125.0 * tmpSamplesPerFrame / tmpFrequency;
                        int tmpPaddingSize = (tmpLayerNum == 3 ? 4 : 1);
                        int tmpBitrateIndex = tmpFrameHeader[2] >> 4;

                        // Check for invalid values
                        if (tmpBitrateIndex < 1 || tmpBitrateIndex > 14 || tmpLayerNum == 0)
                        {
                            stream.Seek(-3, SeekOrigin.Current);
                            continue;
                        }

                        int tmpFrameBitrate = GetBitrate((MpegVersion)tmpMpegID, (MpegLayer)tmpLayerNum, tmpBitrateIndex);
                        int tmpFrameSize = (int)(tmpFrameBitrate * tmpFrameSizeConst) + (tmpUsesPadding * tmpPaddingSize);
                        _headerOffset = stream.Position - 4;

                        if (tmpFrameSize < 8)
                        {
                            stream.Seek(-3, SeekOrigin.Current);
                            continue;
                        }

                        // 7/21/05 - Check for 0x00 or 0xFF at end of last frame
                        // this sucks for tracks that start with silence
                        if (_headerOffset >= 1 && !acceptNullSamples) // if (ftell(fp) >= 5)
                        {
                            stream.Seek(-5, SeekOrigin.Current);
                            byte tmpLastByte = stream.Read1();
                            stream.Seek(4, SeekOrigin.Current);

                            if (tmpFrameBitrate != 320 && (tmpLastByte == 0x00 || tmpLastByte == 0xFF))
                            {
                                // 7/31/05
                                // may be a valid frame - skip its contents to prevent false sync
                                long tmpNewPosition = _headerOffset + tmpFrameSize;
                                if (tmpFrameSize == 0)
                                    tmpNewPosition++;
                                stream.Seek(tmpNewPosition, SeekOrigin.Begin);
                                continue;
                            }
                        }

                        /*if (BR == 0 || FrameSizeConst == 0)
                        {
                            startpos = HeaderOffset+1;
                            fseek(fp, startpos, SEEK_SET);
                            continue;
                        }*/

                        stream.Seek(_headerOffset + tmpFrameSize, SeekOrigin.Begin);
                        if (stream.Read1() == 0xFF)
                        {
                            fh1 = stream.Read1();
                            fh2 = stream.Read1();

                            if (tmpFrameHeader[1] == fh1 &&
                                (tmpFrameHeader[2] & 0x0D) == (fh2 & 0x0D))
                            {
                                // header found
                                break;
                            }
                        }

                        stream.Seek(_headerOffset + 1, SeekOrigin.Begin);
                        continue;
                    }
                }

                _mpegVersion = (MpegVersion)((tmpFrameHeader[1] >> 3) & 0x03);
                _mpegLayer = (MpegLayer)((tmpFrameHeader[1] >> 1) & 0x03);
                _frequency = GetFrequency(_mpegVersion, (tmpFrameHeader[2] >> 2) & 0x03);
                if (_frequency == 0)
                {
                    throw new InvalidDataException(String.Format("'{0}'; cannot determine frequency", path));
                }

                _isPrivate = ((tmpFrameHeader[2] & 0x01) == 0x01);
                _samplesPerFrame = GetSamplesPerFrame(_mpegVersion, _mpegLayer);
                _frameSizeConst = 125.0 * _samplesPerFrame / _frequency;
                _paddingSizeConst = (_mpegLayer == MpegLayer.Layer1 ? 4 : 1);
                _isCopyright = (((tmpFrameHeader[3] >> 3) & 0x01) == 0x01);
                _isOriginal = (((tmpFrameHeader[3] >> 2) & 0x01) == 0x01);
                //tmpModeExtension = (FH[3] >> 4) & 0x03; // not interested, only used in joint-stereo
                //_mpegEmphasis = (MpegEmphasis)(tmpFrameHeader[3] & 0x03);

                if ((tmpFrameHeader[3] >> 6) == 3) _channels = 1; // Single Channel
                else _channels = 2;

                // Read LAME Info Tag
                bool tmpHasLameInfoTag = false;

                stream.Seek(tmpID3v2TagSize + 36, SeekOrigin.Begin);
                Byte[] buf = stream.Read(4);

                if (ByteUtils.Compare(buf, INFO_MARKER)) // CBR
                {
                    tmpHasLameInfoTag = true;
                    _isVBR = false;
                }
                else if (ByteUtils.Compare(buf, XING_MARKER)) // VBR
                {
                    tmpHasLameInfoTag = true;
                    _isVBR = true;
                }

                if (tmpHasLameInfoTag)
                {
                    stream.Seek(4, SeekOrigin.Current);
                    int tmpFrames = stream.ReadInt32();
                    uint tmpBytes = (uint)stream.ReadInt32();

                    if (tmpFrames > 256 && tmpBytes > 50000)
                    {
                        decimal tmpBitrate = tmpBytes / 125.0m / (tmpFrames * _samplesPerFrame / (decimal)_frequency);
                        if (tmpBitrate <= 320 && tmpBitrate >= 32)
                        {
                            _frames = tmpFrames;
                            _bitrate = tmpBitrate;
                            _totalSeconds = (tmpBytes / 125.0m) / _bitrate;
                        }
                    }
                }

                // TODO: Take these 2 lines out
                /*fs.Position = 0;
                CalculateBitrate(fs, null);*/

                if (calculateBitrate)
                {
                    if (_bitrate == 0 || _isVBR == null || _frames == 0 || _totalSeconds == 0)
                    {
                        stream.Position = 0;
                        CalculateBitrate(stream, null);
                    }
                }
            }
        }
Esempio n. 17
0
        private static int GetFrequency(MpegVersion mpegVersion, int frequencyID)
        {
            int tmpFrequency = 0;

            switch (mpegVersion)
            {
                // MPEG-1
                case MpegVersion.Mpeg1:
                    switch (frequencyID)
                    {
                        case 0:
                            tmpFrequency = 44100;
                            break;
                        case 1:
                            tmpFrequency = 48000;
                            break;
                        case 2:
                            tmpFrequency = 32000;
                            break;
                    } // end switch (Frequency)
                    break;

                // MPEG-2
                case MpegVersion.Mpeg2:
                    switch (frequencyID)
                    {
                        case 0:
                            tmpFrequency = 22050;
                            break;
                        case 1:
                            tmpFrequency = 24000;
                            break;
                        case 2:
                            tmpFrequency = 16000;
                            break;
                    } // end switch (Frequency)
                    break;

                // MPEG-2.5
                case MpegVersion.Mpeg25:
                    switch (frequencyID)
                    {
                        case 0:
                            tmpFrequency = 11025;
                            break;
                        case 1:
                            tmpFrequency = 12000;
                            break;
                        case 2:
                            tmpFrequency = 8000;
                            break;
                    } // end switch (Frequency)
                    break;
            } // end switch (ID)

            return tmpFrequency;
        }
Esempio n. 18
0
        public byte[] BuildFrame(
            MpegVersion version,
            MpegLayer layer,
            bool hasCRC,
            int frameSizeOffset,
            int frameSize)
        {
            byte[] buf = Slush.DomainObjects.Mp3.Test.Mp3FrameTest.BuildFrame(
                version,
                layer,
                hasCRC,
                frameSizeOffset,
                frameSize);

            if (UseRandom)
            {
                for (int i = 6; i < buf.Length; i++)
                {
                    buf[i] = (byte)random.Next();
                }
            }
            return buf;
        }
Esempio n. 19
0
        /// <summary>Reads an MP3Frame from a stream</summary>
        /// <remarks>http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm
        /// has some good info</remarks>
        public Mp3Frame(Stream input)
        {
            BinaryReader reader = new BinaryReader(input);
            // try for a header
            long headerStartPosition = input.Position;

            byte[] headerBytes = reader.ReadBytes(4);
            if ((headerBytes[0] == 0xFF) && ((headerBytes[1] & 0xE0) == 0xE0))
            {
                // TODO: could do with a bitstream class here
                mpegVersion = (MpegVersion)((headerBytes[1] & 0x18) >> 3);
                if (mpegVersion == MpegVersion.Reserved)
                {
                    throw new FormatException("Unsupported MPEG Version");
                }

                layer = (MpegLayer)((headerBytes[1] & 0x06) >> 1);
                if (layer != MpegLayer.Layer3)
                {
                    throw new FormatException("Not an MP3");
                }
                crcPresent = (headerBytes[1] & 0x01) == 0x00;
                int bitRateIndex = (headerBytes[2] & 0xF0) >> 4;

                bitRate = (mpegVersion == MpegVersion.Version1) ? bitRatesLayer3Version1[bitRateIndex] :
                          bitRatesLayer3Version2[bitRateIndex];
                int sampleFrequencyIndex = (headerBytes[2] & 0x0C) >> 2;
                if (mpegVersion == MpegVersion.Version1)
                {
                    sampleRate = sampleRatesVersion1[sampleFrequencyIndex];
                }
                else if (mpegVersion == MpegVersion.Version2)
                {
                    sampleRate = sampleRatesVersion2[sampleFrequencyIndex];
                }
                else // mpegVersion == MpegVersion.Version25
                {
                    sampleRate = sampleRatesVersion25[sampleFrequencyIndex];
                }


                bool padding    = (headerBytes[2] & 0x02) == 0x02;
                bool privateBit = (headerBytes[2] & 0x01) == 0x01;
                channelMode = (ChannelMode)((headerBytes[3] & 0xC0) >> 6);
                int  channelExtension = (headerBytes[3] & 0x30) >> 4;
                bool copyright        = (headerBytes[3] & 0x08) == 0x80;
                bool original         = (headerBytes[3] & 0x04) == 0x80;
                int  emphasis         = (headerBytes[3] & 0x03);

                frameLengthInBytes = (144 * 1000 * bitRate) / sampleRate + ((padding) ? 1 : 0);
            }
            else
            {
                input.Position = headerStartPosition;
                throw new FormatException("Not a recognised MP3 block");
            }
            if (crcPresent)
            {
                crc = reader.ReadInt16();
            }

            long dataStartPosition = input.Position;

            input.Position = headerStartPosition;

            rawData = reader.ReadBytes(frameLengthInBytes);
        }
Esempio n. 20
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Mpeg"/> class.
        /// </summary>
        /// <param name="path">The full path of the file.</param>
        /// <param name="calculateBitrate">if set to <c>true</c> the bitrate will be calculated before the constructor returns.</param>
        public Mpeg(string path, bool calculateBitrate)
        {
            _fileName = path;

            using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                int tmpID3v2TagSize = ID3v2.GetTagSize(stream);
                stream.Seek(tmpID3v2TagSize, SeekOrigin.Begin);

                byte[] tmpFrameHeader = new byte[4];

                bool acceptNullSamples = false;
                while (true)
                {
                    int tmpByte = stream.ReadByte(); // keep as ReadByte
                    while (tmpByte != 0xFF && tmpByte != -1)
                    {
                        tmpByte = stream.ReadByte(); // keep as ReadByte
                    }

                    if (tmpByte == -1)
                    {
                        if (acceptNullSamples)
                        {
                            throw new InvalidDataException(string.Format("'{0}': Can't find frame sync", path));
                        }
                        stream.Seek(tmpID3v2TagSize, SeekOrigin.Begin);
                        acceptNullSamples = true;
                        continue;
                    }

                    tmpFrameHeader[0] = (byte)tmpByte;

                    // Get frame header
                    if (stream.Read(tmpFrameHeader, 1, 3) != 3)
                    {
                        throw new InvalidDataException(string.Format("'{0}': Invalid MPEG file; end of stream reached", path));
                    }

                    // No sync
                    if ((tmpFrameHeader[1] >> 5) != 0x07 ||
                        ((tmpFrameHeader[1] >> 1) & 0x03) == 0) // 2/18/05 - ignore reserved layer
                    {
                        stream.Seek(-3, SeekOrigin.Current);
                    }
                    else if (tmpFrameHeader[1] == 0xFF ||
                             ((tmpFrameHeader[1] >> 3) & 0x03) == 1) // 2/19/05 - more bad data
                    {
                        stream.Seek(-3, SeekOrigin.Current);
                    }
                    else
                    {
                        int tmpMpegID    = (tmpFrameHeader[1] >> 3) & 0x03;
                        int tmpLayerNum  = (tmpFrameHeader[1] >> 1) & 0x03;
                        int tmpFrequency = GetFrequency((MpegVersion)tmpMpegID, (tmpFrameHeader[2] >> 2) & 0x03);

                        // Check for invalid frequency
                        if (tmpFrequency == 0)
                        {
                            stream.Seek(-3, SeekOrigin.Current);
                            continue;
                        }

                        int tmpSamplesPerFrame = GetSamplesPerFrame((MpegVersion)tmpMpegID, (MpegLayer)tmpLayerNum);

                        int    tmpUsesPadding    = (tmpFrameHeader[2] >> 1) & 0x01;
                        double tmpFrameSizeConst = 125.0 * tmpSamplesPerFrame / tmpFrequency;
                        int    tmpPaddingSize    = (tmpLayerNum == 3 ? 4 : 1);
                        int    tmpBitrateIndex   = tmpFrameHeader[2] >> 4;

                        // Check for invalid values
                        if (tmpBitrateIndex < 1 || tmpBitrateIndex > 14 || tmpLayerNum == 0)
                        {
                            stream.Seek(-3, SeekOrigin.Current);
                            continue;
                        }

                        int tmpFrameBitrate = GetBitrate((MpegVersion)tmpMpegID, (MpegLayer)tmpLayerNum, tmpBitrateIndex);
                        int tmpFrameSize    = (int)(tmpFrameBitrate * tmpFrameSizeConst) + (tmpUsesPadding * tmpPaddingSize);
                        _headerOffset = stream.Position - 4;

                        if (tmpFrameSize < 8)
                        {
                            stream.Seek(-3, SeekOrigin.Current);
                            continue;
                        }

                        // 7/21/05 - Check for 0x00 or 0xFF at end of last frame
                        // this sucks for tracks that start with silence
                        if (_headerOffset >= 1 && !acceptNullSamples) // if (ftell(fp) >= 5)
                        {
                            stream.Seek(-5, SeekOrigin.Current);
                            byte tmpLastByte = stream.Read1();
                            stream.Seek(4, SeekOrigin.Current);

                            if (tmpFrameBitrate != 320 && (tmpLastByte == 0x00 || tmpLastByte == 0xFF))
                            {
                                // 7/31/05
                                // may be a valid frame - skip its contents to prevent false sync
                                long tmpNewPosition = _headerOffset + tmpFrameSize;
                                if (tmpFrameSize == 0)
                                {
                                    tmpNewPosition++;
                                }
                                stream.Seek(tmpNewPosition, SeekOrigin.Begin);
                                continue;
                            }
                        }

                        /*if (BR == 0 || FrameSizeConst == 0)
                         * {
                         *  startpos = HeaderOffset+1;
                         *  fseek(fp, startpos, SEEK_SET);
                         *  continue;
                         * }*/

                        stream.Seek(_headerOffset + tmpFrameSize, SeekOrigin.Begin);
                        if (stream.Read1() == 0xFF)
                        {
                            fh1 = stream.Read1();
                            fh2 = stream.Read1();

                            if (tmpFrameHeader[1] == fh1 &&
                                (tmpFrameHeader[2] & 0x0D) == (fh2 & 0x0D))
                            {
                                // header found
                                break;
                            }
                        }

                        stream.Seek(_headerOffset + 1, SeekOrigin.Begin);
                        continue;
                    }
                }

                _mpegVersion = (MpegVersion)((tmpFrameHeader[1] >> 3) & 0x03);
                _mpegLayer   = (MpegLayer)((tmpFrameHeader[1] >> 1) & 0x03);
                _frequency   = GetFrequency(_mpegVersion, (tmpFrameHeader[2] >> 2) & 0x03);
                if (_frequency == 0)
                {
                    throw new InvalidDataException(String.Format("'{0}'; cannot determine frequency", path));
                }

                _isPrivate        = ((tmpFrameHeader[2] & 0x01) == 0x01);
                _samplesPerFrame  = GetSamplesPerFrame(_mpegVersion, _mpegLayer);
                _frameSizeConst   = 125.0 * _samplesPerFrame / _frequency;
                _paddingSizeConst = (_mpegLayer == MpegLayer.Layer1 ? 4 : 1);
                _isCopyright      = (((tmpFrameHeader[3] >> 3) & 0x01) == 0x01);
                _isOriginal       = (((tmpFrameHeader[3] >> 2) & 0x01) == 0x01);
                //tmpModeExtension = (FH[3] >> 4) & 0x03; // not interested, only used in joint-stereo
                //_mpegEmphasis = (MpegEmphasis)(tmpFrameHeader[3] & 0x03);

                if ((tmpFrameHeader[3] >> 6) == 3)
                {
                    _channels = 1;                                // Single Channel
                }
                else
                {
                    _channels = 2;
                }

                // Read LAME Info Tag
                bool tmpHasLameInfoTag = false;

                stream.Seek(tmpID3v2TagSize + 36, SeekOrigin.Begin);
                Byte[] buf = stream.Read(4);

                if (ByteUtils.Compare(buf, INFO_MARKER)) // CBR
                {
                    tmpHasLameInfoTag = true;
                    _isVBR            = false;
                }
                else if (ByteUtils.Compare(buf, XING_MARKER)) // VBR
                {
                    tmpHasLameInfoTag = true;
                    _isVBR            = true;
                }

                if (tmpHasLameInfoTag)
                {
                    stream.Seek(4, SeekOrigin.Current);
                    int  tmpFrames = stream.ReadInt32();
                    uint tmpBytes  = (uint)stream.ReadInt32();

                    if (tmpFrames > 256 && tmpBytes > 50000)
                    {
                        decimal tmpBitrate = tmpBytes / 125.0m / (tmpFrames * _samplesPerFrame / (decimal)_frequency);
                        if (tmpBitrate <= 320 && tmpBitrate >= 32)
                        {
                            _frames       = tmpFrames;
                            _bitrate      = tmpBitrate;
                            _totalSeconds = (tmpBytes / 125.0m) / _bitrate;
                        }
                    }
                }

                // TODO: Take these 2 lines out

                /*fs.Position = 0;
                 * CalculateBitrate(fs, null);*/

                if (calculateBitrate)
                {
                    if (_bitrate == 0 || _isVBR == null || _frames == 0 || _totalSeconds == 0)
                    {
                        stream.Position = 0;
                        CalculateBitrate(stream, null);
                    }
                }
            }
        }
Esempio n. 21
0
        private static int GetFrequency(MpegVersion mpegVersion, int frequencyID)
        {
            int tmpFrequency = 0;

            switch (mpegVersion)
            {
            // MPEG-1
            case MpegVersion.Mpeg1:
                switch (frequencyID)
                {
                case 0:
                    tmpFrequency = 44100;
                    break;

                case 1:
                    tmpFrequency = 48000;
                    break;

                case 2:
                    tmpFrequency = 32000;
                    break;
                }     // end switch (Frequency)
                break;

            // MPEG-2
            case MpegVersion.Mpeg2:
                switch (frequencyID)
                {
                case 0:
                    tmpFrequency = 22050;
                    break;

                case 1:
                    tmpFrequency = 24000;
                    break;

                case 2:
                    tmpFrequency = 16000;
                    break;
                }     // end switch (Frequency)
                break;

            // MPEG-2.5
            case MpegVersion.Mpeg25:
                switch (frequencyID)
                {
                case 0:
                    tmpFrequency = 11025;
                    break;

                case 1:
                    tmpFrequency = 12000;
                    break;

                case 2:
                    tmpFrequency = 8000;
                    break;
                }     // end switch (Frequency)
                break;
            } // end switch (ID)

            return(tmpFrequency);
        }
Esempio n. 22
0
 private static int GetBitrate(MpegVersion mpegVersion, MpegLayer mpegLayer, int bitrateIndex)
 {
     return(BitrateTable[(int)mpegVersion][(int)mpegLayer - 1][bitrateIndex - 1]);
 }
Esempio n. 23
0
 static int GetBitRate( MpegVersion version, int layer, int index )
 {
     if( version == MpegVersion.Version10 ) {
         return mpeg10bitrates[layer][index] * 1000;
     } else if( version == MpegVersion.Version20 || version == MpegVersion.Version25 ) {
         return mpeg2025bitrates[layer][index] * 1000;
     }
     throw new ArgumentException( "Unsupported version" + version );
 }
Esempio n. 24
0
 static int CalculateSamplesPerFrame(MpegVersion mpegVersion) => mpegVersion == MpegVersion.One ? 1152 : 576;
Esempio n. 25
0
 static int CalculateSamplesPerFrame(MpegVersion mpegVersion)
 {
     return(mpegVersion == MpegVersion.One ? 1152 : 576);
 }
Esempio n. 26
0
 private static int GetBitrate(MpegVersion mpegVersion, MpegLayer mpegLayer, int bitrateIndex)
 {
     return BitrateTable[(int)mpegVersion][(int)mpegLayer - 1][bitrateIndex - 1];
 }
Esempio n. 27
0
 private void GetVersion(params bool[] twoBits)
 {
     if (twoBits[0] && twoBits[1]) this.mpegVersion = MpegVersion.MpegVersion1;
     else if (twoBits[0] && !twoBits[1]) this.mpegVersion = MpegVersion.MpegVersion2;
     else if (!twoBits[0] && twoBits[1]) this.mpegVersion = MpegVersion.Reserved;
     else if (!twoBits[0] && !twoBits[1]) this.mpegVersion = MpegVersion.MpegVersion25;
 }
Esempio n. 28
0
        private static int GetSamplesPerFrame(MpegVersion mpegVersion, MpegLayer mpegLayer)
        {
            int tmpSamplesPerFrame = 0;

            switch (mpegVersion)
            {
                // MPEG-1
                case MpegVersion.Mpeg1:
                    if (mpegLayer == MpegLayer.Layer1) tmpSamplesPerFrame = 384;
                    else if (mpegLayer == MpegLayer.Layer2 ||
                             mpegLayer == MpegLayer.Layer3) tmpSamplesPerFrame = 1152;
                    break;

                // MPEG-2/2.5
                case MpegVersion.Mpeg2:
                case MpegVersion.Mpeg25:
                    if (mpegLayer == MpegLayer.Layer1) tmpSamplesPerFrame = 384;
                    else if (mpegLayer == MpegLayer.Layer2) tmpSamplesPerFrame = 1152;
                    else if (mpegLayer == MpegLayer.Layer3) tmpSamplesPerFrame = 576;
                    break;
            } // end switch (ID)

            return tmpSamplesPerFrame;
        }
Esempio n. 29
0
        /// <summary>checks if the four bytes represent a valid header,
        /// if they are, will parse the values into local properties
        /// </summary>
        private bool IsValidHeader(byte[] headerBytes)
        {
            if ((headerBytes[0] == 0xFF) && ((headerBytes[1] & 0xE0) == 0xE0))
            {
                // TODO: could do with a bitstream class here
                mpegVersion = (MpegVersion)((headerBytes[1] & 0x18) >> 3);
                if (mpegVersion == MpegVersion.Reserved)
                {
                    //throw new FormatException("Unsupported MPEG Version");
                    return false;
                }

                layer = (MpegLayer)((headerBytes[1] & 0x06) >> 1);

                if (layer == MpegLayer.Reserved)
                {
                    return false;
                }
                int layerIndex = this.layer == MpegLayer.Layer1 ? 0 : this.layer == MpegLayer.Layer2 ? 1: 2;
                crcPresent = (headerBytes[1] & 0x01) == 0x00;
                int bitRateIndex = (headerBytes[2] & 0xF0) >> 4;
                if (bitRateIndex == 15)
                {
                    // invalid index
                    return false;
                }
                int versionIndex = this.mpegVersion == Wave.MpegVersion.Version1 ? 0 : 1;
                this.bitRate = bitRates[versionIndex, layerIndex, bitRateIndex] * 1000;
                if (bitRate == 0)
                {
                    return false;
                }
                int sampleFrequencyIndex = (headerBytes[2] & 0x0C) >> 2;
                if (sampleFrequencyIndex == 3)
                {
                    return false;
                }
                if (mpegVersion == MpegVersion.Version1)
                    sampleRate = sampleRatesVersion1[sampleFrequencyIndex];
                else if (mpegVersion == MpegVersion.Version2)
                    sampleRate = sampleRatesVersion2[sampleFrequencyIndex];
                else // mpegVersion == MpegVersion.Version25
                    sampleRate = sampleRatesVersion25[sampleFrequencyIndex];

                bool padding = (headerBytes[2] & 0x02) == 0x02;
                bool privateBit = (headerBytes[2] & 0x01) == 0x01;
                channelMode = (ChannelMode)((headerBytes[3] & 0xC0) >> 6);
                int channelExtension = (headerBytes[3] & 0x30) >> 4;
                bool copyright = (headerBytes[3] & 0x08) == 0x08;
                bool original = (headerBytes[3] & 0x04) == 0x04;
                int emphasis = (headerBytes[3] & 0x03);

                int nPadding = padding ? 1 : 0;

                this.samplesInFrame = samplesPerFrame[versionIndex, layerIndex];
                int coefficient = this.samplesInFrame / 8;
                if (this.layer == MpegLayer.Layer1)
                {
                    this.frameLengthInBytes = (coefficient * bitRate / sampleRate + nPadding) * 4;
                }
                else
                {
                    frameLengthInBytes = (coefficient * bitRate) / sampleRate + nPadding;
                }

                if (this.frameLengthInBytes > MaxFrameLength)
                {
                    return false;
                }
                return true;
            }
            return false;
        }
Esempio n. 30
0
        /// <summary>Reads an MP3Frame from a stream</summary>
        /// <remarks>http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm 
        /// has some good info</remarks>
        public Mp3Frame(Stream input)
        {
            BinaryReader reader = new BinaryReader(input);
            // try for a header
            long headerStartPosition = input.Position;
            byte[] headerBytes = reader.ReadBytes(4);

            // Added -jam to play wrapped mp3 files via RIFF
            headerBytes = CheckForRiff(input, reader, headerBytes);

            if ((headerBytes[0] == 0xFF) && ((headerBytes[1] & 0xE0) == 0xE0))
            {
                // TODO: could do with a bitstream class here
                mpegVersion = (MpegVersion)((headerBytes[1] & 0x18) >> 3);
                if (mpegVersion == MpegVersion.Reserved)
                {
                    throw new FormatException("Unsupported MPEG Version");
                }

                layer = (MpegLayer)((headerBytes[1] & 0x06) >> 1);
                if (layer != MpegLayer.Layer3)
                {
                    throw new FormatException("Not an MP3");
                }
                crcPresent = (headerBytes[1] & 0x01) == 0x00;
                int bitRateIndex = (headerBytes[2] & 0xF0) >> 4;

                bitRate = (mpegVersion == MpegVersion.Version1) ? bitRatesLayer3Version1[bitRateIndex] :
                    bitRatesLayer3Version2[bitRateIndex];
                int sampleFrequencyIndex = (headerBytes[2] & 0x0C) >> 2;
                if (mpegVersion == MpegVersion.Version1)
                    sampleRate = sampleRatesVersion1[sampleFrequencyIndex];
                else if (mpegVersion == MpegVersion.Version2)
                    sampleRate = sampleRatesVersion2[sampleFrequencyIndex];
                else // mpegVersion == MpegVersion.Version25
                    sampleRate = sampleRatesVersion25[sampleFrequencyIndex];


                bool padding = (headerBytes[2] & 0x02) == 0x02;
                bool privateBit = (headerBytes[2] & 0x01) == 0x01;
                channelMode = (ChannelMode) ((headerBytes[3] & 0xC0) >> 6);
                int channelExtension = (headerBytes[3] & 0x30) >> 4;
                bool copyright = (headerBytes[3] & 0x08) == 0x80;
                bool original = (headerBytes[3] & 0x04) == 0x80;
                int emphasis = (headerBytes[3] & 0x03);

                frameLengthInBytes = (144 * 1000 * bitRate) / sampleRate + ((padding) ? 1 : 0);

            }
            else
            {
                input.Position = headerStartPosition;
                throw new FormatException("Not a recognised MP3 block");
            }
            if (crcPresent)
                crc = reader.ReadInt16();

            long dataStartPosition = input.Position;
            input.Position = headerStartPosition;

            rawData = reader.ReadBytes(frameLengthInBytes);

        }
Esempio n. 31
0
 private static int?GetBitrate(byte three, MpegVersion version, MpegLayer layer)
 {
     if (version == MpegVersion.MPEG1)
     {
         if (layer == MpegLayer.Layer1)
         {
             if (CompBit(three, 1, 4, false, false, false, false))
             {
                 return(null);
             }
             if (CompBit(three, 1, 4, false, false, false, true))
             {
                 return(32);
             }
             if (CompBit(three, 1, 4, false, false, true, false))
             {
                 return(64);
             }
             if (CompBit(three, 1, 4, false, false, true, true))
             {
                 return(96);
             }
             if (CompBit(three, 1, 4, false, true, false, false))
             {
                 return(128);
             }
             if (CompBit(three, 1, 4, false, true, false, true))
             {
                 return(160);
             }
             if (CompBit(three, 1, 4, false, true, true, false))
             {
                 return(192);
             }
             if (CompBit(three, 1, 4, false, true, true, true))
             {
                 return(224);
             }
             if (CompBit(three, 1, 4, true, false, false, false))
             {
                 return(256);
             }
             if (CompBit(three, 1, 4, true, false, false, true))
             {
                 return(288);
             }
             if (CompBit(three, 1, 4, true, false, true, false))
             {
                 return(320);
             }
             if (CompBit(three, 1, 4, true, false, true, true))
             {
                 return(352);
             }
             if (CompBit(three, 1, 4, true, true, false, false))
             {
                 return(384);
             }
             if (CompBit(three, 1, 4, true, true, false, true))
             {
                 return(416);
             }
             if (CompBit(three, 1, 4, true, true, true, false))
             {
                 return(448);
             }
             if (CompBit(three, 1, 4, true, true, true, true))
             {
                 return(null);
             }
         }
         else if (layer == MpegLayer.Layer2)
         {
             if (CompBit(three, 1, 4, false, false, false, false))
             {
                 return(null);
             }
             if (CompBit(three, 1, 4, false, false, false, true))
             {
                 return(32);
             }
             if (CompBit(three, 1, 4, false, false, true, false))
             {
                 return(45);
             }
             if (CompBit(three, 1, 4, false, false, true, true))
             {
                 return(56);
             }
             if (CompBit(three, 1, 4, false, true, false, false))
             {
                 return(64);
             }
             if (CompBit(three, 1, 4, false, true, false, true))
             {
                 return(80);
             }
             if (CompBit(three, 1, 4, false, true, true, false))
             {
                 return(96);
             }
             if (CompBit(three, 1, 4, false, true, true, true))
             {
                 return(112);
             }
             if (CompBit(three, 1, 4, true, false, false, false))
             {
                 return(128);
             }
             if (CompBit(three, 1, 4, true, false, false, true))
             {
                 return(160);
             }
             if (CompBit(three, 1, 4, true, false, true, false))
             {
                 return(192);
             }
             if (CompBit(three, 1, 4, true, false, true, true))
             {
                 return(224);
             }
             if (CompBit(three, 1, 4, true, true, false, false))
             {
                 return(256);
             }
             if (CompBit(three, 1, 4, true, true, false, true))
             {
                 return(320);
             }
             if (CompBit(three, 1, 4, true, true, true, false))
             {
                 return(384);
             }
             if (CompBit(three, 1, 4, true, true, true, true))
             {
                 return(null);
             }
         }
         else if (layer == MpegLayer.Layer3)
         {
             if (CompBit(three, 1, 4, false, false, false, false))
             {
                 return(null);
             }
             if (CompBit(three, 1, 4, false, false, false, true))
             {
                 return(32);
             }
             if (CompBit(three, 1, 4, false, false, true, false))
             {
                 return(40);
             }
             if (CompBit(three, 1, 4, false, false, true, true))
             {
                 return(45);
             }
             if (CompBit(three, 1, 4, false, true, false, false))
             {
                 return(56);
             }
             if (CompBit(three, 1, 4, false, true, false, true))
             {
                 return(64);
             }
             if (CompBit(three, 1, 4, false, true, true, false))
             {
                 return(80);
             }
             if (CompBit(three, 1, 4, false, true, true, true))
             {
                 return(96);
             }
             if (CompBit(three, 1, 4, true, false, false, false))
             {
                 return(112);
             }
             if (CompBit(three, 1, 4, true, false, false, true))
             {
                 return(128);
             }
             if (CompBit(three, 1, 4, true, false, true, false))
             {
                 return(160);
             }
             if (CompBit(three, 1, 4, true, false, true, true))
             {
                 return(192);
             }
             if (CompBit(three, 1, 4, true, true, false, false))
             {
                 return(224);
             }
             if (CompBit(three, 1, 4, true, true, false, true))
             {
                 return(256);
             }
             if (CompBit(three, 1, 4, true, true, true, false))
             {
                 return(320);
             }
             if (CompBit(three, 1, 4, true, true, true, true))
             {
                 return(null);
             }
         }
     }
     return(null);
 }
Esempio n. 32
0
		public static int XingHeaderOffset(MpegVersion version, MpegChannelMode channelMode)
		{
			if (version == MpegVersion.One)
			{
				if (channelMode == MpegChannelMode.SingleChannel)
					return 0x15;
				else
					return 0x24;
			}
			else
			{
				if (channelMode == MpegChannelMode.SingleChannel)
					return 0x0D;
				else
					return 0x15;
			}
		}
Esempio n. 33
0
      //////////////////////////////////////////////////////////////////////////
      // private methods
      //////////////////////////////////////////////////////////////////////////

      private void Read ()
      {
         // Since we've likely just looked for the ID3v1 tag, start at the end of the
         // file where we're least likely to have to have to move the disk head.

         long last = file.LastFrameOffset;

         if (last < 0)
         {
            TagLibDebugger.Debug ("Mpeg.Properties.Read() -- Could not find a valid last MPEG frame in the stream.");
            return;
         }

         file.Seek (last);
         MpegHeader last_header = new MpegHeader (file.ReadBlock (4));

         long first = file.FirstFrameOffset;

         if (first < 0)
         {
            TagLibDebugger.Debug ("Mpeg.Properties.Read() -- Could not find a valid first MPEG frame in the stream.");
            return;
         }

         if(!last_header.IsValid)
         {
            long pos = last;

            while (pos > first)
            {
               pos = file.PreviousFrameOffset (pos);

               if(pos < 0)
                  break;

               file.Seek (pos);
               MpegHeader header = new MpegHeader (file.ReadBlock (4));

               if (header.IsValid)
               {
                  last_header = header;
                  last = pos;
                  break;
               }
            }
         }

         // Now jump back to the front of the file and read what we need from there.

         file.Seek (first);
         MpegHeader first_header = new MpegHeader (file.ReadBlock (4));

         if (!first_header.IsValid || !last_header.IsValid)
         {
            TagLibDebugger.Debug ("Mpeg.Properties.Read() -- Page headers were invalid.");
            return;
         }

         // Check for a Xing header that will help us in gathering information about a
         // VBR stream.

         int xing_header_offset = MpegXingHeader.XingHeaderOffset (first_header.Version,
                                      first_header.ChannelMode);

         file.Seek (first + xing_header_offset);
         MpegXingHeader xing_header = new MpegXingHeader (file.ReadBlock (16));

         // Read the length and the bitrate from the Xing header.

         if(xing_header.IsValid && first_header.SampleRate > 0 && xing_header.TotalFrames > 0)
         {
            int [] block_size = {0, 384, 1152, 1152};
            
            double time_per_frame = block_size [first_header.Layer];
            time_per_frame = first_header.SampleRate > 0 ? time_per_frame / first_header.SampleRate : 0;
            duration = new TimeSpan((int)(time_per_frame * xing_header.TotalFrames) * TimeSpan.TicksPerSecond);
            bitrate = (int) (duration > TimeSpan.Zero ? ((xing_header.TotalSize * 8L) / duration.TotalSeconds) / 1000 : 0);
         }

         // Since there was no valid Xing header found, we hope that we're in a constant
         // bitrate file.

         // TODO: Make this more robust with audio property detection for VBR without a
         // Xing header.

         else if (first_header.FrameLength > 0 && first_header.Bitrate > 0)
         {
            int frames = (int) ((last - first) / first_header.FrameLength + 1);

            duration = TimeSpan.FromSeconds ((double) (first_header.FrameLength * frames) / (double) (first_header.Bitrate * 125) + 0.5);
            bitrate = first_header.Bitrate;
         }
         
         
         sample_rate    = first_header.SampleRate;
         channels       = first_header.ChannelMode == MpegChannelMode.SingleChannel ? 1 : 2;
         version        = first_header.Version;
         layer          = first_header.Layer;
         channel_mode   = first_header.ChannelMode;
         is_copyrighted = first_header.IsCopyrighted;
         is_original    = first_header.IsOriginal;
      }