static OptionalHeader ReadXingHeader([NotNull] FrameReader reader, [NotNull] FrameHeader header) { // Xing header (if present) is located after the side info reader.BaseStream.Position = reader.FrameStart + 4 + header.SideInfoLength; var result = new OptionalHeader(); var headerId = reader.ReadHeaderId(); if (!headerId.Equals("Xing", StringComparison.Ordinal) && !headerId.Equals("Info", StringComparison.Ordinal)) { return(result); } // Both fields are optional, even if the header is present var flags = reader.ReadUInt32BigEndian(); if ((flags & 1) == 1) { result.FrameCount = reader.ReadUInt32BigEndian(); } if ((flags >> 1 & 1) == 1) { result.ByteCount = reader.ReadUInt32BigEndian(); } return(result); }
static int DetermineBitRate([NotNull] FrameHeader frameHeader, OptionalHeader optionalHeader) { // If the BitRate can't be calculated because of an incomplete or missing VBR header, assume CBR if (optionalHeader.Incomplete) { return(frameHeader.BitRate * 1000); } return((int)Math.Round( optionalHeader.ByteCount * 8 / (optionalHeader.FrameCount * frameHeader.SamplesPerFrame / (double)frameHeader.SampleRate))); }
static OptionalHeader ReadVbriHeader([NotNull] FrameReader reader) { // VBRI header (if present) is located 32 bytes past the frame header reader.BaseStream.Position = reader.FrameStart + 36; var result = new OptionalHeader(); if (!reader.ReadHeaderId().Equals("VBRI", StringComparison.Ordinal)) { return(result); } reader.BaseStream.Seek(6, SeekOrigin.Current); result.ByteCount = reader.ReadUInt32BigEndian(); result.FrameCount = reader.ReadUInt32BigEndian(); return(result); }