/// <summary> /// Reads all <see cref="FlacMetadata"/> from the specified <paramref name="stream"/>. /// </summary> /// <param name="stream">The stream which contains the <see cref="FlacMetadata"/>.</param> /// <returns>All <see cref="FlacMetadata"/>.</returns> public static IEnumerable <FlacMetadata> ReadAllMetadataFromStream(Stream stream) { while (true) { FlacMetadata data = FromStream(stream); yield return(data); if (data == null || data.IsLastMetaBlock) { break; } } }
public unsafe static FlacMetadata FromStream(Stream stream) { bool lastBlock = false; FlacMetaDataType type = FlacMetaDataType.Undef; int length = 0; byte[] b = new byte[4]; if (stream.Read(b, 0, 4) <= 0) { throw new FlacException(new EndOfStreamException("Could not read metadata"), FlacLayer.Metadata); fixed(byte *headerBytes = b) { FlacBitReader bitReader = new FlacBitReader(headerBytes, 0); lastBlock = bitReader.ReadBits(1) == 1; type = (FlacMetaDataType)bitReader.ReadBits(7); length = (int)bitReader.ReadBits(24); ////1000 0000 //if (((b[0] & 0x80) >> 7) == 1) // lastBlock = true; //type = (FlacMetaDataType)(b[0] & 0x7F); //int length = (b[1] + (b[2] << 8) + (b[3] << 16)); } FlacMetadata data; long streamStartPosition = stream.Position; if ((int)type < 0 || (int)type > 6) return(null); } else { switch (type) { case FlacMetaDataType.StreamInfo: data = new FlacMetadataStreamInfo(stream, length, lastBlock); break; case FlacMetaDataType.Seektable: data = new FlacMetadataSeekTable(stream, length, lastBlock); break; default: data = new FlacMetadata(type, lastBlock, length); break; } } stream.Seek(length - (stream.Position - streamStartPosition), SeekOrigin.Current); return(data); }
private unsafe List<FlacFrameInformation> ScanThisShit(FlacMetadataStreamInfo streamInfo) { Stream stream = _stream; //if (!(stream is BufferedStream)) // stream = new BufferedStream(stream); byte[] buffer = new byte[BufferSize]; stream.Position = 4; //fLaC //skip the metadata FlacMetadata.SkipMetadata(stream); List<FlacFrameInformation> frames = new List<FlacFrameInformation>(); FlacFrameInformation frameInfo = new FlacFrameInformation(); frameInfo.IsFirstFrame = true; FlacFrameHeader baseHeader = null; while (true) { int read = stream.Read(buffer, 0, buffer.Length); if (read <= FlacConstant.FrameHeaderSize) break; fixed (byte* bufferPtr = buffer) { byte* ptr = bufferPtr; //for (int i = 0; i < read - FlacConstant.FrameHeaderSize; i++) while ((bufferPtr + read - FlacConstant.FrameHeaderSize) > ptr) { if (*ptr++ == 0xFF && (*ptr & 0xF8) == 0xF8) //check sync { byte* ptrSafe = ptr; ptr--; FlacFrameHeader tmp; if (IsFrame(ref ptr, streamInfo, out tmp)) { FlacFrameHeader header = tmp; if (frameInfo.IsFirstFrame) { baseHeader = header; frameInfo.IsFirstFrame = false; } if (baseHeader != null && baseHeader.IsFormatEqualTo(header)) { frameInfo.StreamOffset = stream.Position - read + ((ptrSafe - 1) - bufferPtr); frameInfo.Header = header; frames.Add(frameInfo); frameInfo.SampleOffset += header.BlockSize; } else { ptr = ptrSafe; } } else { ptr = ptrSafe; } } } } stream.Position -= FlacConstant.FrameHeaderSize; } return frames; }
/// <summary> /// Initializes a new instance of the <see cref="FlacFile" /> class. /// </summary> /// <param name="stream">Stream which contains flac data which should be decoded.</param> /// <param name="scanFlag">Scan mode which defines how to scan the flac data for frames.</param> /// <param name="onscanFinished"> /// Callback which gets called when the pre scan processes finished. Should be used if the /// <paramref name="scanFlag" /> argument is set the <see cref="FlacPreScanMode.Async" />. /// </param> public FlacFile(Stream stream, FlacPreScanMode scanFlag, Action <FlacPreScanFinishedEventArgs> onscanFinished) { if (stream == null) { throw new ArgumentNullException(); } if (!stream.CanRead) { throw new ArgumentException("Stream is not readable.", "stream"); } _stream = stream; _closeStream = true; //skip ID3v2 while (ID3v2.SkipTag(stream)) { } //read fLaC sync var beginSync = new byte[4]; int read = stream.Read(beginSync, 0, beginSync.Length); if (read < beginSync.Length) { throw new EndOfStreamException("Can not read \"fLaC\" sync."); } if (beginSync[0] == 0x66 && beginSync[1] == 0x4C && //Check for 'fLaC' signature beginSync[2] == 0x61 && beginSync[3] == 0x43) { //read metadata List <FlacMetadata> metadata = FlacMetadata.ReadAllMetadataFromStream(stream).ToList(); Metadata = metadata.AsReadOnly(); if (metadata.Count <= 0) { throw new FlacException("No Metadata found.", FlacLayer.Metadata); } var streamInfo = metadata.First(x => x.MetaDataType == FlacMetaDataType.StreamInfo) as FlacMetadataStreamInfo; if (streamInfo == null) { throw new FlacException("No StreamInfo-Metadata found.", FlacLayer.Metadata); } _streamInfo = streamInfo; _waveFormat = CreateWaveFormat(streamInfo); Log.Verbose("Flac StreamInfo found -> WaveFormat: " + _waveFormat); Log.Verbose("Flac-File-Metadata read."); } else { throw new FlacException("Invalid Flac-File. \"fLaC\" Sync not found.", FlacLayer.OutSideOfFrame); } //prescan stream if (scanFlag != FlacPreScanMode.None) { var scan = new FlacPreScan(stream); scan.ScanFinished += (s, e) => { onscanFinished?.Invoke(e); }; scan.ScanStream(_streamInfo, scanFlag); _scan = scan; } }
public FlacFile(Stream stream, FlacPreScanMethodMode?scanFlag, Action <FlacPreScanFinishedEventArgs> onscanFinished) { if (stream == null) { throw new ArgumentNullException(); } if (!stream.CanRead) { throw new ArgumentException("Stream is not readable.", "stream"); } _stream = stream; //skip ID3v2 Tags.ID3.ID3v2.SkipTag(stream); int read = 0; //read fLaC sync byte[] beginSync = new byte[4]; read = stream.Read(beginSync, 0, beginSync.Length); if (read < beginSync.Length) { throw new EndOfStreamException("Can not read \"fLaC\" sync."); } if (beginSync[0] == 0x66 && beginSync[1] == 0x4C && beginSync[2] == 0x61 && beginSync[3] == 0x43) { //read metadata var metadata = FlacMetadata.AllDataFromStream(stream); Metadata = metadata; if (metadata == null || metadata.Count <= 0) { throw new FlacException("No Metadata found.", FlacLayer.Metadata); } FlacMetadataStreamInfo streamInfo = metadata.Where(x => x.MetaDataType == FlacMetaDataType.StreamInfo).First() as FlacMetadataStreamInfo; if (streamInfo == null) { new FlacException("No StreamInfo-Metadata found.", FlacLayer.Metadata); } _streamInfo = streamInfo; _waveFormat = new WaveFormat(streamInfo.SampleRate, (short)streamInfo.BitsPerSample, (short)streamInfo.Channels, AudioEncoding.Pcm); Debug.WriteLine("Flac StreamInfo found -> WaveFormat: " + _waveFormat.ToString()); Debug.WriteLine("Flac-File-Metadata read."); } else { throw new FlacException("Invalid Flac-File. \"fLaC\" Sync not found.", FlacLayer.Top); } //prescan stream if (scanFlag != null) { FlacPreScan scan = new FlacPreScan(stream); scan.ScanFinished += (s, e) => { if (onscanFinished != null) { onscanFinished(e); } }; scan.ScanStream(_streamInfo, (FlacPreScanMethodMode)scanFlag); _scan = scan; } }
public static unsafe FlacMetadata FromStream(Stream stream) { bool lastBlock = false; FlacMetaDataType type = FlacMetaDataType.Undef; int length = 0; byte[] b = new byte[4]; if (stream.Read(b, 0, 4) <= 0) throw new FlacException(new EndOfStreamException("Could not read metadata"), FlacLayer.Metadata); fixed (byte* headerBytes = b) { FlacBitReader bitReader = new FlacBitReader(headerBytes, 0); lastBlock = bitReader.ReadBits(1) == 1; type = (FlacMetaDataType)bitReader.ReadBits(7); length = (int)bitReader.ReadBits(24); ////1000 0000 //if (((b[0] & 0x80) >> 7) == 1) // lastBlock = true; //type = (FlacMetaDataType)(b[0] & 0x7F); //int length = (b[1] + (b[2] << 8) + (b[3] << 16)); } FlacMetadata data; long streamStartPosition = stream.Position; if ((int)type < 0 || (int)type > 6) return null; else { switch (type) { case FlacMetaDataType.StreamInfo: data = new FlacMetadataStreamInfo(stream, length, lastBlock); break; case FlacMetaDataType.Seektable: data = new FlacMetadataSeekTable(stream, length, lastBlock); break; default: data = new FlacMetadata(type, lastBlock, length); break; } } stream.Seek(length - (stream.Position - streamStartPosition), SeekOrigin.Current); return data; }
/// <summary> /// Reads and returns a single <see cref="FlacMetadata"/> from the specified <paramref name="stream"/>. /// </summary> /// <param name="stream">The stream which contains the <see cref="FlacMetadata"/>.</param> /// <returns>Returns the read <see cref="FlacMetadata"/>.</returns> public static unsafe FlacMetadata FromStream(Stream stream) { bool lastBlock; FlacMetaDataType type; int length; byte[] b = new byte[4]; if (stream.Read(b, 0, 4) <= 0) throw new FlacException(new EndOfStreamException("Could not read metadata"), FlacLayer.Metadata); fixed (byte* headerBytes = b) { FlacBitReader bitReader = new FlacBitReader(headerBytes, 0); lastBlock = bitReader.ReadBits(1) == 1; type = (FlacMetaDataType)bitReader.ReadBits(7); length = (int)bitReader.ReadBits(24); } FlacMetadata data; long streamStartPosition = stream.Position; if ((int)type < 0 || (int)type > 6) return null; switch (type) { case FlacMetaDataType.StreamInfo: data = new FlacMetadataStreamInfo(stream, length, lastBlock); break; case FlacMetaDataType.Seektable: data = new FlacMetadataSeekTable(stream, length, lastBlock); break; default: data = new FlacMetadata(type, lastBlock, length); break; } stream.Seek(length - (stream.Position - streamStartPosition), SeekOrigin.Current); return data; }