private bool IsCorrectHeader(Packet headerPacket, byte headerType) { byte[] header = Read(headerPacket.FileOffset, VorbisHeaderInfo.PacketHeaderSize); if (header[VorbisHeaderInfo.HeaderTypeIndex] != headerType) return false; string magicSeq = Encoding.ASCII.GetString(header, VorbisHeaderInfo.MagicSeqIndex, VorbisHeaderInfo.MagicSeqSize); if (magicSeq != VorbisHeaderInfo.MagicSeq) return false; return true; }
private bool IsVorbisStream(Packet idHeader, Packet commentHeader, Packet setupHeader) { if (idHeader.Size < VorbisHeaderInfo.PacketHeaderSize) return false; if (commentHeader.Size < VorbisHeaderInfo.PacketHeaderSize) return false; if (setupHeader.Size < VorbisHeaderInfo.PacketHeaderSize) return false; return IsCorrectHeader(idHeader, VorbisHeaderInfo.IdHeaderType) && IsCorrectHeader(commentHeader, VorbisHeaderInfo.CommentHeaderType) && IsCorrectHeader(setupHeader, VorbisHeaderInfo.SetupHeaderType); }
public IEnumerable<Packet> ReadPackets(IEnumerable<Page> pages) { if (pages == null) throw new ArgumentNullException("pages"); long fileOffset = 0; int size = 0; int firstPage = 0; int pageIndex = 0; int numberOfSegments = 0; bool hasPacket = false; foreach (var page in pages) { //if the previous page had unfinished packet, this page must be marked as continuation if (hasPacket && page.PageType != PageType.Continuation) throw new InvalidStreamException("Packet didn't finish on previous page, but next page is not marked as Continuation"); foreach (var segment in page.Segments) { //start new packet if (!hasPacket) { fileOffset = segment.FileOffset; firstPage = pageIndex; hasPacket = true; } numberOfSegments++; size += segment.Size; //packet spans across several segments if (segment.Size == ExtendedSegmentSize) continue; Packet p = new Packet(fileOffset, size, firstPage, numberOfSegments); yield return p; //reset values size = 0; fileOffset = 0; hasPacket = false; numberOfSegments = 0; } pageIndex++; } yield break; }
private void ParseCommentHeader(VorbisStream vorbis, Packet packet) { FileStream.Seek(packet.FileOffset + VorbisHeaderInfo.VendorLengthIndex, SeekOrigin.Begin); uint vendorLength = BitConverter.ToUInt32(ReadNoSeek(4), 0); var vendorString = Encoding.UTF8.GetString(ReadNoSeek((int) vendorLength), 0, (int) vendorLength); uint userCommentListLength = BitConverter.ToUInt32(ReadNoSeek(4), 0); IList<string> userComments = new List<string>((int) userCommentListLength); for (uint i = 0; i < userCommentListLength; i++) { uint length = BitConverter.ToUInt32(ReadNoSeek(4), 0); string userComment = Encoding.UTF8.GetString(ReadNoSeek((int) length), 0, (int) length); userComments.Add(userComment); } bool framingFlag = BitConverter.ToBoolean(ReadNoSeek(1), 0); if (!framingFlag) throw new InvalidStreamException("Framing flag at the end of the comment header is not set"); vorbis.Comments = new VorbisComments(vendorString, userComments); }
private void ParseIdHeder(VorbisStream vorbisStream, Packet idHeader) { byte[] identificationHeader = Read(idHeader.FileOffset, idHeader.Size); byte version = identificationHeader[VorbisHeaderInfo.VersionIndex]; byte audioChannels = identificationHeader[VorbisHeaderInfo.AudioChannelsIndex]; uint audioSampleRate = BitConverter.ToUInt32(identificationHeader, VorbisHeaderInfo.AudioSampleRateIndex); int maxBitrate = BitConverter.ToInt32(identificationHeader, VorbisHeaderInfo.MaximumBitrateIndex); int nominalBitrate = BitConverter.ToInt32(identificationHeader, VorbisHeaderInfo.NominalBitrateIndex); int minBitrate = BitConverter.ToInt32(identificationHeader, VorbisHeaderInfo.MinimumBitrateIndex); uint blockSize0 = (uint) Math.Pow(2, (identificationHeader[VorbisHeaderInfo.BlockSizeIndex] & VorbisHeaderInfo.BlockSize0Mask)); uint blockSize1 = (uint) Math.Pow(2, identificationHeader[VorbisHeaderInfo.BlockSizeIndex] >> 4); byte framingFlag = identificationHeader[VorbisHeaderInfo.FramingFlagIndex]; vorbisStream.Version = version; vorbisStream.AudioChannels = audioChannels; vorbisStream.SampleRate = audioSampleRate; vorbisStream.BlockSize0 = blockSize0; vorbisStream.BlockSize1 = blockSize1; vorbisStream.FramingFlag = framingFlag; vorbisStream.MaxBitrate = maxBitrate; vorbisStream.MinBitrate = minBitrate; vorbisStream.NominalBitrate = nominalBitrate; }