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); }
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; } } }
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); } }
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); } }
private MP3Frame GetNextFrame(Stream stream) { MP3Frame frame; do { frame = MP3Frame.FromStream(stream, ref _frameBuffer); } while (frame == null); return(frame); }
private MP3Frame ReadNextMP3Frame() { MP3Frame frame = MP3Frame.FromStream(_stream, ref _frameBuffer); if (frame != null && _frameInfoCollection != null) { _frameInfoCollection.PlaybackIndex++; } return(frame); }
protected virtual void Dispose(bool disposing) { if (!_disposed) { if (disposing) { for (int i = 0; i < Count; i++) { this[i] = null; } frame = null; } } _disposed = true; }
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); } }
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); }
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); }
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; }
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); }
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); }
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; }
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; }
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(); } }
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; }
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; }
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; }
public static MP3Frame FromStream(Stream stream) { MP3Frame frame = new MP3Frame(stream); return(frame.FindFrame(stream, true) ? frame : null); }
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; } } }
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; } }
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; }
public static MP3Frame FromStream(Stream stream) { MP3Frame frame = new MP3Frame(stream); return frame.FindFrame(stream, true) ? frame : null; }
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; }