예제 #1
0
        private static int CalcOffset(MP3Frame frame)
        {
            int offset = 0;

            if (frame.MPEGVersion == MpegVersion.Version1)
            {
                if (frame.ChannelMode != MP3ChannelMode.Mono)
                {
                    offset = 32 + 4;
                }
                else
                {
                    offset = 17 + 4;
                }
            }
            else if (frame.MPEGVersion == MpegVersion.Version2)
            {
                if (frame.ChannelMode != MP3ChannelMode.Mono)
                {
                    offset = 17 + 4;
                }
                else
                {
                    offset = 9 + 4;
                }
            }
            else
            {
                return(-1);
            }

            return(offset);
        }
예제 #2
0
 protected void Dispose(bool disposing)
 {
     lock (_lockObject)
     {
         if (disposing)
         {
             if (_converter != null)
             {
                 _converter.Dispose();
                 _converter = null;
             }
             if (_stream != null)
             {
                 _stream.Dispose();
                 _stream = null;
             }
             if (_frameInfoCollection != null)
             {
                 _frameInfoCollection.Dispose();
                 _frameInfoCollection = null;
             }
             _pcmDstBuffer = null;
             _frame        = null;
         }
     }
 }
예제 #3
0
        public bool AddFromMP3Stream(Stream stream)
        {
            try
            {
                MP3FrameInfo info = new MP3FrameInfo();

                info.StreamPosition = stream.Position;
                info.SampleIndex    = TotalSamples;
                frame = MP3Frame.FromStream(stream);
                if (frame != null)
                {
                    info.SampleAmount = frame.SampleCount;
                    info.Size         = Convert.ToInt32(stream.Position - info.StreamPosition);
                    TotalSamples     += frame.SampleCount;

                    Add(info);
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            catch (Exception)
            {
                return(false);
            }
        }
예제 #4
0
        public int Read(byte[] buffer, int offset, int count)
        {
            if (IsEOF)
            {
                return(0);
            }

            try
            {
                int read = 0;
                lock (_lockObject)
                {
                    read += CheckForOverflows(buffer, ref offset, count);
                    if (read == count)
                    {
                        return(read); //if we've already read enough -> exit
                    }
                    while (read < count)
                    {
                        try
                        {
                            _frame = ReadNextMP3Frame();
                            if (_frame == null)
                            {
                                IsEOF = true;
                                break;
                            }

                            int converted = _converter.Convert(_frameBuffer, _frame.FrameLength, _pcmDstBuffer, 0);
                            int BTCC      = Math.Min(count - read, converted);

                            Array.Copy(_pcmDstBuffer, 0, buffer, offset, BTCC);
                            offset += BTCC;
                            read   += BTCC;

                            /*
                             * If there are any overflows -> store them in a
                             * buffer to use it next time.
                             */
                            _overflows    = ((converted > BTCC) ? (converted - BTCC) : 0);
                            _bufferoffset = ((converted > BTCC) ? (BTCC) : 0);
                        }
                        catch (Exception ex)
                        {
                            Debugger.Break();
                            Debug.WriteLine("Mp3Stream::Read: " + ex.ToString());
                        }
                    }

                    _position += read;

                    return(read);
                }
            }
            catch (EndOfStreamException)
            {
                return(-1);
            }
        }
예제 #5
0
        private MP3Frame GetNextFrame(Stream stream)
        {
            MP3Frame frame;

            do
            {
                frame = MP3Frame.FromStream(stream, ref _frameBuffer);
            } while (frame == null);

            return(frame);
        }
예제 #6
0
        private MP3Frame ReadNextMP3Frame()
        {
            MP3Frame frame = MP3Frame.FromStream(_stream, ref _frameBuffer);

            if (frame != null && _frameInfoCollection != null)
            {
                _frameInfoCollection.PlaybackIndex++;
            }

            return(frame);
        }
예제 #7
0
 protected virtual void Dispose(bool disposing)
 {
     if (!_disposed)
     {
         if (disposing)
         {
             for (int i = 0; i < Count; i++)
             {
                 this[i] = null;
             }
             frame = null;
         }
     }
     _disposed = true;
 }
예제 #8
0
 private static bool CheckForValidXingHeader(MP3Frame frame, int offset)
 {
     byte[] data = null;
     if (frame.ReadData(ref data, 0) < 4)
     {
         return(false);
     }
     if (data[offset + 0] == 'X' && data[offset + 1] == 'i' && data[offset + 2] == 'n' && data[offset + 3] == 'g')
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
예제 #9
0
        protected override int GetInputData(ref byte[] inputDataBuffer, int requested)
        {
            MP3Frame frame = ReadNextMP3Frame(ref inputDataBuffer);

            if (frame == null)
            {
                inputDataBuffer = new byte[0];
                return(0);
            }

            if (inputDataBuffer.Length > frame.FrameLength)
            {
                Array.Clear(inputDataBuffer, frame.FrameLength, inputDataBuffer.Length - frame.FrameLength);
            }

            return(frame.FrameLength);
        }
예제 #10
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);
        }
예제 #11
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;
        }
예제 #12
0
        private static int ReadHeaderFlags(MP3Frame frame, int offset)
        {
            byte[] data = null;
            if (frame.ReadData(ref data, 0) < 4)
            {
                throw new System.IO.EndOfStreamException();
            }
            int i = 0;

            i   = data[offset + 0];
            i <<= 8;
            i  |= data[offset + 1];
            i <<= 8;
            i  |= data[offset + 2];
            i <<= 8;
            i  |= data[offset + 3];

            return(i);
        }
예제 #13
0
파일: Mp3Frame.cs 프로젝트: yazici/AudioLab
        public static MP3Frame FromStream(Stream stream, ref byte[] data)
        {
            MP3Frame frame = new MP3Frame(stream);

            if (frame.FindFrame(stream, false))
            {
                data = data.CheckBuffer(frame.FrameLength);
                Array.Copy(frame._headerBuffer, 0, data, 0, 4);
                int read = stream.Read(data, 4, frame.FrameLength - 4);
                if (read != frame.FrameLength - 4)
                {
                    return(null);
                }

                return(frame);
            }

            return(null);
        }
예제 #14
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;
        }
예제 #15
0
        private static int CalcOffset(MP3Frame frame)
        {
            int offset = 0;
            if (frame.MPEGVersion == MpegVersion.Version1)
            {
                if (frame.ChannelMode != MP3ChannelMode.Mono)
                    offset = 32 + 4;
                else
                    offset = 17 + 4;
            }
            else if (frame.MPEGVersion == MpegVersion.Version2)
            {
                if (frame.ChannelMode != MP3ChannelMode.Mono)
                    offset = 17 + 4;
                else
                    offset = 9 + 4;
            }
            else
            {
                return -1;
            }

            return offset;
        }
예제 #16
0
        private void BufferProc(object o)
        {
            if (_stream == null || _stream.CanRead == false)
            {
                throw new Exception("Mp3WebStream not initialized");
            }

            MP3Frame frame = GetNextFrame(_stream);

            int          channels  = frame.ChannelMode == MP3ChannelMode.Stereo ? 2 : 1;
            AcmConverter converter = new AcmConverter(new MP3Format(frame.SampleRate, frame.ChannelCount, frame.FrameLength, frame.BitRate));

            _waveFormat = converter.DestinationFormat;

            byte[] buffer = new byte[16384 * 4];
            _buffer = new FixedSizeBuffer <byte>(converter.DestinationFormat.BytesPerSecond * 10);

            ManualResetEvent resetEvent = o as ManualResetEvent;

            resetEvent.Set();

            do
            {
                if (_buffer.Buffered >= _buffer.Length * 0.85 && !_disposing)
                {
                    Thread.Sleep(250);
                    continue;
                }
                try
                {
                    frame = GetNextFrame(_stream);
                    //_frameBuffer is set in GetNextFrame
                    int count = converter.Convert(_frameBuffer, frame.FrameLength, buffer, 0);
                    if (count > 0)
                    {
                        int written = _buffer.Write(buffer, 0, count);
                    }
                }
                catch (MmException)
                {
                    _disposing = true;
                    ThreadPool.QueueUserWorkItem((c) =>
                    {
                        while (_bufferThread.ThreadState != System.Threading.ThreadState.Stopped)
                        {
                            ;
                        }
                        CreateStream(false);
                    });
                }
                catch (WebException)
                {
                    InitializeConnection();
                }
                catch (IOException)
                {
                    InitializeConnection();
                }
            } while (!_disposing);

            if (converter != null)
            {
                converter.Dispose();
            }
        }
예제 #17
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;
        }
예제 #18
0
        private static int ReadHeaderFlags(MP3Frame frame, int offset)
        {
            byte[] data = null;
            if (frame.ReadData(ref data, 0) < 4)
                throw new System.IO.EndOfStreamException();
            int i = 0;
            i = data[offset + 0];
            i <<= 8;
            i |= data[offset + 1];
            i <<= 8;
            i |= data[offset + 2];
            i <<= 8;
            i |= data[offset + 3];

            return i;
        }
예제 #19
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;
        }
예제 #20
0
파일: Mp3Frame.cs 프로젝트: yazici/AudioLab
        public static MP3Frame FromStream(Stream stream)
        {
            MP3Frame frame = new MP3Frame(stream);

            return(frame.FindFrame(stream, true) ? frame : null);
        }
예제 #21
0
 protected void Dispose(bool disposing)
 {
     lock (_lockObject)
     {
         if (disposing)
         {
             if (_converter != null)
             {
                 _converter.Dispose();
                 _converter = null;
             }
             if (_stream != null)
             {
                 _stream.Dispose();
                 _stream = null;
             }
             if (_frameInfoCollection != null)
             {
                 _frameInfoCollection.Dispose();
                 _frameInfoCollection = null;
             }
             _pcmDstBuffer = null;
             _frame = null;
         }
     }
 }
예제 #22
0
        public int Read(byte[] buffer, int offset, int count)
        {
            if (IsEOF)
                return 0;

            try
            {
                int read = 0;
                lock (_lockObject)
                {
                    read += CheckForOverflows(buffer, ref offset, count);
                    if (read == count)
                        return read; //if we've already read enough -> exit

                    while (read < count)
                    {
                        try
                        {
                            _frame = ReadNextMP3Frame();
                            if (_frame == null)
                            {
                                IsEOF = true;
                                break;
                            }

                            int converted = _converter.Convert(_frameBuffer, _frame.FrameLength, _pcmDstBuffer, 0);
                            int BTCC = Math.Min(count - read, converted);

                            Array.Copy(_pcmDstBuffer, 0, buffer, offset, BTCC);
                            offset += BTCC;
                            read += BTCC;

                            /*
                             * If there are any overflows -> store them in a
                             * buffer to use it next time.
                             */
                            _overflows = ((converted > BTCC) ? (converted - BTCC) : 0);
                            _bufferoffset = ((converted > BTCC) ? (BTCC) : 0);
                        }
                        catch (Exception ex)
                        {
                            Debugger.Break();
                            Debug.WriteLine("Mp3Stream::Read: " + ex.ToString());
                        }
                    }

                    _position += read;

                    return read;
                }
            }
            catch (EndOfStreamException)
            {
                return -1;
            }
        }
예제 #23
0
 private static bool CheckForValidXingHeader(MP3Frame frame, int offset)
 {
     byte[] data = null;
     if (frame.ReadData(ref data, 0) < 4)
         return false;
     if (data[offset + 0] == 'X' && data[offset + 1] == 'i' && data[offset + 2] == 'n' && data[offset + 3] == 'g')
     {
         return true;
     }
     else
         return false;
 }
예제 #24
0
 public static MP3Frame FromStream(Stream stream)
 {
     MP3Frame frame = new MP3Frame(stream);
     return frame.FindFrame(stream, true) ? frame : null;
 }
예제 #25
0
        public static MP3Frame FromStream(Stream stream, ref byte[] data)
        {
            MP3Frame frame = new MP3Frame(stream);
            if (frame.FindFrame(stream, false))
            {
                data = data.CheckBuffer(frame.FrameLength);
                Array.Copy(frame._headerBuffer, 0, data, 0, 4);
                int read = stream.Read(data, 4, frame.FrameLength - 4);
                if (read != frame.FrameLength - 4)
                    return null;

                return frame;
            }

            return null;
        }