示例#1
0
        private void ParseForMp3Frames(Stream stream, bool enableSeeking)
        {
            Mp3Frame frame = null;
            long     offsetOfFirstFrame = 0;

            stream = new BufferedStream(stream);

            if (enableSeeking)
            {
                while (ID3v2.SkipTag(stream))
                {
                    /* skip all id3 tags (see https://github.com/filoe/cscore/issues/63)
                     * there are some files with multiple id3v2 tags
                     * not sure whether this is according to the id3 specification but we have to handle it anyway
                     * as long as the SkipTag method returns true, another id3 tag has been found
                     */
                }
            }

            while (frame == null)
            {
                if (enableSeeking && stream.IsEndOfStream())
                {
                    break;
                }

                if (enableSeeking)
                {
                    offsetOfFirstFrame = stream.Position;
                }
                frame = Mp3Frame.FromStream(stream);
            }

            if (frame == null)
            {
                throw new Exception("Could not find any MP3-Frames in the stream.");
            }

            if (enableSeeking)
            {
                XingHeader xingHeader = XingHeader.FromFrame(frame);
                if (xingHeader != null)
                {
                    offsetOfFirstFrame = stream.Position;
                }
            }
            _inputFormat = new Mp3Format(frame.SampleRate, frame.ChannelCount, frame.FrameLength, frame.BitRate);

            //Prescan stream
            if (enableSeeking)
            {
                _frameInfoCollection = new FrameInfoCollection();
                while (_frameInfoCollection.AddFromMp3Stream(stream))
                {
                }

                stream.Position = offsetOfFirstFrame;
            }
        }
示例#2
0
        /// <summary>
        /// Gets the <see cref="XingHeader"/> of a <see cref="Mp3Frame"/>. If the <paramref name="frame"/> does not has an <see cref="XingHeader"/> the return value will be null.
        /// </summary>
        /// <param name="frame"><see cref="Mp3Frame"/> which should get checked whether it contains a <see cref="XingHeader"/>.</param>
        /// <returns><see cref="XingHeader"/> of the specified <paramref name="frame"/> or null.</returns>
        public static XingHeader FromFrame(Mp3Frame frame)
        {
            XingHeader header = new XingHeader();
            int        offset = CalcOffset(frame);

            if (offset == -1)
            {
                return(null);
            }

            if (CheckForValidXingHeader(frame, offset))
            {
                header._startIndex = offset;
                offset             = offset + 4;
            }
            else
            {
                return(null);
            }

            header.HeaderFlags = (XingHeaderFlags)ReadHeaderFlags(frame, offset);
            offset             = offset + 4;

            if ((header.HeaderFlags & XingHeaderFlags.Frames) != 0)
            {
                header._framesOffset = offset;
                offset += 4;
            }
            if ((header.HeaderFlags & XingHeaderFlags.Bytes) != 0)
            {
                header._bytesOffset = offset;
                offset += 4;
            }
            if ((header.HeaderFlags & XingHeaderFlags.Toc) != 0)
            {
                header._tocOffset = offset;
                offset           += 100;
            }
            if ((header.HeaderFlags & XingHeaderFlags.QualityIndicator) != 0)
            {
                header._qualityIndicator = ReadHeaderFlags(frame, offset);
                offset += 4;
            }
            header._endIndex = offset;
            return(header);
        }
示例#3
0
        public static XingHeader FromFrame(MP3Frame frame)
        {
            XingHeader header = new XingHeader();
            int        offset = CalcOffset(frame);

            if (offset == -1)
            {
                return(null);
            }

            if (CheckForValidXingHeader(frame, offset))
            {
                header.startIndex = offset;
                offset            = offset + 4;
            }
            else
            {
                return(null);
            }

            header.HeaderFlags = (XingHeaderFlags)ReadHeaderFlags(frame, offset);
            offset             = offset + 4;

            if ((header.HeaderFlags & XingHeaderFlags.Frames) != 0)
            {
                header.framesOffset = offset;
                offset += 4;
            }
            if ((header.HeaderFlags & XingHeaderFlags.Bytes) != 0)
            {
                header.bytesOffset = offset;
                offset            += 4;
            }
            if ((header.HeaderFlags & XingHeaderFlags.Toc) != 0)
            {
                header.tocOffset = offset;
                offset          += 100;
            }
            if ((header.HeaderFlags & XingHeaderFlags.VbrScale) != 0)
            {
                header.vbrScale = ReadHeaderFlags(frame, offset);
                offset         += 4;
            }
            header.endIndex = offset;
            return(header);
        }
示例#4
0
        /// <summary>
        /// Gets the <see cref="XingHeader"/> of a <see cref="Mp3Frame"/>. If the <paramref name="frame"/> does not has an <see cref="XingHeader"/> the return value will be null.
        /// </summary>
        /// <param name="frame"><see cref="Mp3Frame"/> which should get checked whether it contains a <see cref="XingHeader"/>.</param>
        /// <returns><see cref="XingHeader"/> of the specified <paramref name="frame"/> or null.</returns>
        public static XingHeader FromFrame(Mp3Frame frame)
        {
            XingHeader header = new XingHeader();
            int offset = CalcOffset(frame);
            if (offset == -1)
                return null;

            if (CheckForValidXingHeader(frame, offset))
            {
                header._startIndex = offset;
                offset = offset + 4;
            }
            else
            {
                return null;
            }

            header.HeaderFlags = (XingHeaderFlags)ReadHeaderFlags(frame, offset);
            offset = offset + 4;

            if ((header.HeaderFlags & XingHeaderFlags.Frames) != 0)
            {
                header._framesOffset = offset;
                offset += 4;
            }
            if ((header.HeaderFlags & XingHeaderFlags.Bytes) != 0)
            {
                header._bytesOffset = offset;
                offset += 4;
            }
            if ((header.HeaderFlags & XingHeaderFlags.Toc) != 0)
            {
                header._tocOffset = offset;
                offset += 100;
            }
            if ((header.HeaderFlags & XingHeaderFlags.QualityIndicator) != 0)
            {
                header._qualityIndicator = ReadHeaderFlags(frame, offset);
                offset += 4;
            }
            header._endIndex = offset;
            return header;
        }
示例#5
0
        public static XingHeader FromFrame(MP3Frame frame)
        {
            XingHeader header = new XingHeader();
            int offset = CalcOffset(frame);
            if (offset == -1)
                return null;

            if (CheckForValidXingHeader(frame, offset))
            {
                header.startIndex = offset;
                offset = offset + 4;
            }
            else
            {
                return null;
            }

            header.HeaderFlags = (XingHeaderFlags)ReadHeaderFlags(frame, offset);
            offset = offset + 4;

            if ((header.HeaderFlags & XingHeaderFlags.Frames) != 0)
            {
                header.framesOffset = offset;
                offset += 4;
            }
            if ((header.HeaderFlags & XingHeaderFlags.Bytes) != 0)
            {
                header.bytesOffset = offset;
                offset += 4;
            }
            if ((header.HeaderFlags & XingHeaderFlags.Toc) != 0)
            {
                header.tocOffset = offset;
                offset += 100;
            }
            if ((header.HeaderFlags & XingHeaderFlags.VbrScale) != 0)
            {
                header.vbrScale = ReadHeaderFlags(frame, offset);
                offset += 4;
            }
            header.endIndex = offset;
            return header;
        }
示例#6
0
        private void ParseForMP3Frame(Stream stream)
        {
            if (_parsedStream)
            {
                return;
            }

            MP3Frame frame = null;
            long     offsetOfFirstFrame = 0;

            while (frame == null && !stream.IsEndOfStream())
            {
                offsetOfFirstFrame = stream.Position;
                frame = MP3Frame.FromStream(stream);
            }

            if (frame == null)
            {
                throw new MP3Exception("Could not find any MP3-Frames in the stream.");
            }

            XingHeader xingHeader = XingHeader.FromFrame(frame);

            if (xingHeader != null)
            {
                offsetOfFirstFrame = stream.Position;
            }

            _inputFormat = new MP3Format(frame.SampleRate, frame.ChannelCount, frame.FrameLength, frame.BitRate); //implement VBR?

            //Prescan stream
            _frameInfoCollection = new FrameInfoCollection();
            while (_frameInfoCollection.AddFromMP3Stream(stream))
            {
                ;
            }

            stream.Position = offsetOfFirstFrame;

            _parsedStream = true;
        }
示例#7
0
        private void ParseForMp3Frames(Stream stream, bool enableSeeking)
        {
            Mp3Frame frame = null;
            long     offsetOfFirstFrame = 0;

            ID3v2.SkipTag(stream);

            while (frame == null && !stream.IsEndOfStream())
            {
                offsetOfFirstFrame = stream.Position;
                frame = Mp3Frame.FromStream(stream);
            }

            if (frame == null)
            {
                throw new Exception("Could not find any MP3-Frames in the stream.");
            }

            if (stream.CanSeek)
            {
                XingHeader xingHeader = XingHeader.FromFrame(frame);
                if (xingHeader != null)
                {
                    offsetOfFirstFrame = stream.Position;
                }
            }
            _inputFormat = new Mp3Format(frame.SampleRate, frame.ChannelCount, frame.FrameLength, frame.BitRate);
            //todo: implement VBR

            //Prescan stream
            if (enableSeeking)
            {
                _frameInfoCollection = new FrameInfoCollection();
                while (_frameInfoCollection.AddFromMp3Stream(stream))
                {
                }

                stream.Position = offsetOfFirstFrame;
            }
        }
示例#8
0
        public MP3Stream(Stream stream, bool scanStream, int lengthOffset)
        {
            int frameLength = 0;

            if (scanStream)
            {
                _frameInfoCollection = new FrameInfoCollection();
            }
            else
            {
                _frameInfoCollection = null;
            }

            _dataStartIndex = stream.Position;
            do
            {
                _frame = MP3Frame.FromStream(stream);
                if (_frame == null && stream.IsEndOfStream())
                {
                    throw new FormatException("Stream is no MP3-stream. No MP3-Frame was found.");
                }
            } while (_frame == null && !stream.IsEndOfStream());

            frameLength = _frame.FrameLength;
            _sampleRate = _frame.SampleRate;
            XingHeader  = XingHeader.FromFrame(_frame); //The first frame can contain a Xingheader
            if (XingHeader != null)
            {
                //Todo: dataInitPosition = stream.Position
                _dataStartIndex = stream.Position;
            }

            _dataLength = stream.Length - _dataStartIndex - lengthOffset;

            if (scanStream)
            {
                stream.Position = _dataStartIndex;
                PreScanFile(stream);
                CanSeek = true;
            }
            else
            {
                CanSeek = false;
            }

            stream.Position = _dataStartIndex;

            /*
             * bytes * 8 (8bits perbyte) / ms = totalbits / totalms = bits per ms
             */
            if (scanStream)
            {
                _bitRate = ((_dataLength * 8.0) / ((double)_frameInfoCollection.TotalSamples / (double)_sampleRate));
            }
            else
            {
                _bitRate = ((_frame.BitRate) / 1);
            }
            MP3Format  = new MP3Format(_sampleRate, _frame.ChannelCount, frameLength, (int)Math.Round(_bitRate));
            _converter = new AcmConverter(MP3Format);
            WaveFormat = _converter.DestinationFormat;

            //_bytesPerSample = (WaveFormat.BitsPerSample / 8 * WaveFormat.Channels);
            _pcmDstBuffer = new byte[SamplesPerFrame * WaveFormat.BytesPerBlock * 2];

            stream.Position = _dataStartIndex;
            _stream         = stream;
        }