예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MonkeysAudio"/> class.
        /// </summary>
        /// <param name="path">The path.</param>
        public MonkeysAudio(string path)
        {
            using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                // Skip ID3v2 tag
                int tmpID3v2TagSize = ID3v2.GetTagSize(stream);
                int tmpID3v1TagSize = ID3v1.GetTagSize(stream);
                int tmpAPEv2TagSize = APEv2.GetTagSize(stream);
                stream.Seek(tmpID3v2TagSize, SeekOrigin.Begin);

                byte[] identifier = stream.Read(4);
                if (ByteUtils.Compare(identifier, MAC_IDENTIFIER, 4) == false)
                {
                    throw new InvalidDataException("Invalid Monkey's Audio file");
                }

                byte[] buf = stream.Read(4);

                _version = buf[0] + (buf[1] << 8);
                int blocksPerFrame;
                int finalBlocks;

                if (_version >= 3980 && _version <= 3990)
                {
                    buf = stream.Read(4);
                    int descriptorLength = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
                    stream.Seek(descriptorLength - 12, SeekOrigin.Current); // skip DESCRIPTOR

                    buf = stream.Read(4);
                    _compressionLevel = buf[0] + (buf[1] << 8);

                    blocksPerFrame = stream.ReadInt32LittleEndian();
                    finalBlocks    = stream.ReadInt32LittleEndian();
                    _frames        = stream.ReadInt32LittleEndian();

                    buf = stream.Read(4);
                    // skip bits per sample
                    _channels = buf[2] + (buf[3] << 8);

                    _frequency = stream.ReadInt32LittleEndian();
                }
                else if (_version <= 3970)
                {
                    // TODO: This section needs work

                    _compressionLevel = buf[2] + (buf[3] << 8);

                    buf = stream.Read(24);

                    // skip format flags
                    _channels = buf[2] + (buf[3] << 8);

                    _frequency = buf[4] + (buf[5] << 8) + (buf[6] << 16) + (buf[7] << 32);

                    if (_version >= 3950)
                    {
                        blocksPerFrame = 73728 * 4;
                    }
                    else if (_version >= 3900 || (_version >= 3800 && _compressionLevel == COMPRESSION_LEVEL_EXTRA_HIGH))
                    {
                        blocksPerFrame = 73728;
                    }
                    else
                    {
                        blocksPerFrame = 9216;
                    }

                    // TODO: This is definitely f****d up
                    finalBlocks = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
                    _frames     = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
                }
                else
                {
                    throw new NotImplementedException(string.Format("MAC {0:0.00} not supported", _version / 1000.0));
                }

                long totalBlocks = ((_frames - 1) * blocksPerFrame) + finalBlocks;

                long totalSize = stream.Length - stream.Position - tmpAPEv2TagSize - tmpID3v1TagSize;

                _totalSeconds = totalBlocks / (decimal)_frequency;
                _bitrate      = totalSize / (_totalSeconds * 125.0m);
            }
        }
예제 #2
0
        private readonly int _channels = 2; // TODO

        /// <summary>
        /// Initializes a new instance of the <see cref="Musepack"/> class.
        /// </summary>
        /// <param name="path">The path of the file.</param>
        public Musepack(string path)
        {
            using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                // Skip ID3v2 tag
                int tmpID3v2TagSize = ID3v2.GetTagSize(stream);
                int tmpID3v1TagSize = ID3v1.GetTagSize(stream);
                int tmpAPEv2TagSize = APEv2.GetTagSize(stream);
                stream.Seek(tmpID3v2TagSize, SeekOrigin.Begin);

                _streamVersion = 0;

                byte[] byteArray    = stream.Read(32);
                int[]  integerArray = new int[8];
                for (int i = 0; i < 8; i++)
                {
                    integerArray[i] = (byteArray[i * 4]) +
                                      (byteArray[i * 4 + 1] << 8) +
                                      (byteArray[i * 4 + 2] << 16) +
                                      (byteArray[i * 4 + 3] << 24);
                }

                // Size TODO - ignore Lyrics3
                long audioDataLength = stream.Length - tmpID3v2TagSize - tmpID3v1TagSize - tmpAPEv2TagSize;

                // Stream version
                if (integerArray[0] == STREAM_VERSION_70_ID)
                {
                    _streamVersion = 7;
                }
                else if (integerArray[0] == STREAM_VERSION_71_ID)
                {
                    _streamVersion = 7.1m;
                }
                else
                {
                    switch ((byteArray[1] % 32) / 2)
                    {
                    case 3:
                        _streamVersion = 4;
                        break;

                    case 7:
                        _streamVersion = 5;
                        break;

                    case 11:
                        _streamVersion = 6;
                        break;
                    }
                }

                if (_streamVersion == 0)
                {
                    throw new InvalidDataException("Unrecognized MPC stream");
                }

                // Sample rate
                _frequency = _sampleRates[byteArray[10] & 0x03];

                // Channels
                if (_streamVersion == 7 || _streamVersion == 7.1m)
                {
                    if ((byteArray[11] % 128) < 64)
                    {
                        _mode = "Stereo";
                    }
                    else
                    {
                        _mode = "Joint Stereo";
                    }
                }
                else
                {
                    if ((byteArray[2] % 128) == 0)
                    {
                        _mode = "Stereo";
                    }
                    else
                    {
                        _mode = "Joint Stereo";
                    }
                }

                // Frames
                if (_streamVersion == 4)
                {
                    _frames = integerArray[1] >> 16;
                }
                else
                {
                    _frames = integerArray[1];
                }

                _totalSeconds = _frames * 1152 / (decimal)_frequency;
                _bitrate      = (audioDataLength / _totalSeconds) / 125.0m;
            }
        }
예제 #3
0
파일: Mpeg.cs 프로젝트: superowner/IdSharp
        private void CalculateBitrate(Stream stream, CInterestedFrames InterestedFrames)
        {
            int totalTagSize = ID3v2.GetTagSize(stream);

            totalTagSize += ID3v1.GetTagSize(stream);
            totalTagSize += APEv2.GetTagSize(stream);

            Int64 audioLength = stream.Length - totalTagSize;

            _bitrate      = 0;
            _isVBR        = null;
            _frames       = 0;
            _totalSeconds = 0;

            String step = "";

            try
            {
                int BR, Padding;
                int FrameSize;

                int TotalBR     = 0;
                int FrameOffset = 0;
                //Int64 TagOffset = 0;
                bool   bTrusting = true;
                bool   ignoreall = false;
                Byte[] FH        = new Byte[4];
                bool   mPerfect  = true;

                stream.Position = _headerOffset;

                //                if (_headerOffset > 0)
                //                {
                //                    TagOffset = _headerOffset;
                //                }

                int offset     = 0;
                int frameCount = 0;
                int FirstBR    = 0;

                int    audioDataSize = (int)(stream.Length - _headerOffset);
                Byte[] audioData     = new Byte[audioDataSize];
                //Int64 startoffset = stream.Position;
                int BufLen = stream.Read(audioData, 0, audioDataSize);
                while (offset < BufLen - 16 && !ignoreall)
                {
                    bool reservedlayer = false;

                    // Find FrameSync
                    if (FindFrameSync(FH, audioData, BufLen, ref FrameOffset, ref offset, ref mPerfect, ref ignoreall, ref bTrusting, ref reservedlayer))
                    {
                        FrameOffset = 0;

                        int bitrateIndex = FH[2] >> 4;
                        if (bitrateIndex <= 0 || bitrateIndex >= 15)
                        {
                            offset -= 3;
                            continue;
                        }

                        Padding = (FH[2] >> 1) & 0x01;
                        BR      = GetBitrate(_mpegVersion, _mpegLayer, bitrateIndex);

                        if (BR == 0 || BR % 8 != 0)
                        {
                            offset -= 3;
                            continue;
                        }

                        //step = "last good frame @ " + String(startoffset + offset - 4) + ", frame " +
                        //       String(_frames + 1);

                        // todo: put back later

                        /*if (InterestedFrames != NULL)
                         * {
                         *  if (((_frames + 1) * _samplesperframe / (float)_Frequency) * 75.0 >= InterestedFrames->CurrentFrame())
                         *  {
                         *      if (_frames == 0 || InterestedFrames->NoAccomodation)
                         *      {
                         *          InterestedFrames->SetCurrentByteOffset(startoffset + offset - 4);
                         *          InterestedFrames->SetCurrentFrameOffset(_frames);
                         *      }
                         *      InterestedFrames->SetCurrentByteEndOffset(startoffset + offset - 4);
                         *      InterestedFrames->Cur += 1;
                         *  }
                         *  else
                         *  {
                         *      InterestedFrames->SetCurrentByteOffset(startoffset + offset - 4);
                         *      InterestedFrames->SetCurrentFrameOffset(_frames);
                         *  }
                         * }*/

                        if (_isVBR != true)
                        {
                            if (TotalBR == 0)
                            {
                                FirstBR = BR;
                            }
                            else if (BR != FirstBR)
                            {
                                _isVBR = true;
                            }
                        }

                        TotalBR += BR;

                        FrameSize = (int)(BR * _frameSizeConst + Padding * _paddingSizeConst);

                        offset += FrameSize - 4;
                        frameCount++;
                    }
                }// end while

                if (frameCount == 0)
                {
                    throw new InvalidDataException(String.Format("No frames found in {0}", _fileName));
                }

                _frames = frameCount;
                if (_isVBR == null)
                {
                    _bitrate = FirstBR;
                    _isVBR   = false;
                }
                else
                {
                    _bitrate = TotalBR / _frames;
                }

                if (_bitrate == 0)
                {
                    throw new InvalidDataException(String.Format("Error determining bitrate: {0}", _fileName));
                }

                _totalSeconds = (audioLength / 125.0m) / _bitrate;
            }
            catch (Exception ex)
            {
                throw new Exception(String.Format("Error calculating bitrate; {0}", step), ex);
            }
        }
예제 #4
0
파일: Flac.cs 프로젝트: superowner/IdSharp
        /// <summary>
        /// Initializes a new instance of the <see cref="Flac"/> class.
        /// </summary>
        /// <param name="path">The path of the file.</param>
        public Flac(string path)
        {
            try
            {
                using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    // Skip ID3v2 tag
                    int tmpID3v2TagSize = ID3v2.GetTagSize(stream);
                    int tmpID3v1TagSize = ID3v1.GetTagSize(stream);
                    int tmpAPEv2TagSize = APEv2.GetTagSize(stream);
                    stream.Seek(tmpID3v2TagSize, SeekOrigin.Begin);

                    // Read flac marker
                    byte[] flacMarker = new Byte[4];
                    stream.Read(flacMarker, 0, 4);
                    if (ByteUtils.Compare(flacMarker, FLAC_MARKER) == false)
                    {
                        throw new InvalidDataException("No header found");
                    }

                    // skip frame header and stuff we're not interested in
                    stream.Seek(14, SeekOrigin.Current);

                    byte[] buf = stream.Read(8);

                    _frequency = (buf[0] << 12) + (buf[1] << 4) + (buf[2] >> 4);
                    _channels  = ((buf[2] >> 1) & 0x03) + 1;
                    _samples   = ((buf[3] & 0x0F) << 32) + (buf[4] << 24) +
                                 (buf[5] << 16) + (buf[6] << 8) + buf[7];

                    _totalSeconds = _samples / (decimal)_frequency;

                    // Find first sync
                    // TODO: There's probably a better way to do this.. also an embedded PICTURE might
                    // cause a false sync. Not high priority since it will only cause a slight error
                    // in bitrate calculation if a false sync is found.
                    int c = stream.ReadByte(); // keep as ReadByte
                    while (c != -1)
                    {
                        if (c == 0xFF)
                        {
                            c = stream.ReadByte(); // keep as ReadByte
                            if (c >= 0xF8 && c <= 0xFB)
                            {
                                break;
                            }
                        }
                        else
                        {
                            c = stream.ReadByte(); // keep as ReadByte
                        }
                    }

                    if (c == -1)
                    {
                        throw new InvalidDataException("No sync found");
                    }

                    long startaudio = stream.Position;
                    long totalsize  = stream.Length - startaudio - tmpAPEv2TagSize - tmpID3v1TagSize;
                    _bitrate = totalsize / (_totalSeconds * 125);
                }
            }
            catch (InvalidDataException ex)
            {
                throw new InvalidDataException(String.Format("Cannot read FLAC file '{0}'", path), ex);
            }
        }