Esempio n. 1
0
        internal XingHeader ReadXingHeader()
        {
            var result = new XingHeader();

            var headerId = new string(ReadChars(4));

            if (headerId != "Xing" && headerId != "Info")
            {
                return(result);
            }

            // The flags DWORD indicates whether the frame and byte counts are present:
            uint flags = ReadUInt32BigEndian();

            if ((flags & 0x1) == 1)
            {
                result.FrameCount = ReadUInt32BigEndian();
            }

            if ((flags >> 1 & 0x1) == 1)
            {
                result.ByteCount = ReadUInt32BigEndian();
            }

            return(result);
        }
Esempio n. 2
0
        public AudioInfo ReadAudioInfo(Stream stream)
        {
            Contract.Ensures(Contract.Result <AudioInfo>() != null);

            using (var reader = new FrameReader(stream))
            {
                // Seek to the first valid frame header:
                FrameHeader frameHeader;
                do
                {
                    reader.SeekToNextFrame();
                    frameHeader = new FrameHeader(reader.ReadBytes(4));
                } while (!reader.VerifyFrameSync(frameHeader));

                if (frameHeader.Layer != "III")
                {
                    throw new UnsupportedAudioException(string.Format(CultureInfo.InvariantCulture,
                                                                      Resources.AudioInfoDecoderLayerError, frameHeader.Layer));
                }

                // Seek past the CRC, if present:
                if (frameHeader.HasCrc)
                {
                    reader.BaseStream.Seek(2, SeekOrigin.Current);
                }

                // Seek past the side information:
                reader.BaseStream.Seek(GetSideInfoLength(frameHeader.ChannelMode, frameHeader.MpegVersion),
                                       SeekOrigin.Current);

                // Read the XING header (if present):
                XingHeader xingHeader = reader.ReadXingHeader();

                // If the byte count isn't present in the Xing header, use the file length:
                if (xingHeader.ByteCount == 0)
                {
                    xingHeader.ByteCount = (uint)reader.BaseStream.Length;
                }

                // Calculate the (approximate) sample count:
                uint sampleCount = frameHeader.MpegVersion == "1"
                    ? xingHeader.FrameCount * 1152
                    : xingHeader.FrameCount * 576;

                // Calculate the bitrate from the VBR header, or use the information from the first frame:
                int bitRate = sampleCount > 0
                    ? CalculateBitRate(xingHeader.ByteCount, sampleCount, frameHeader.SampleRate)
                    : frameHeader.BitRate;

                var format = new StringBuilder(bitRate.ToString(CultureInfo.CurrentCulture));
                format.Append("kbps MPEG ");
                format.Append(frameHeader.MpegVersion);
                format.Append(" Layer ");
                format.Append(frameHeader.Layer);

                return(new AudioInfo(format.ToString(), frameHeader.ChannelMode == "Mono" ? 1 : 2, 0,
                                     frameHeader.SampleRate, sampleCount));
            }
        }