private AudioHeader(uint flags, long streamLength, TagLib.Mpeg.XingHeader xingHeader, TagLib.Mpeg.VBRIHeader vbriHeader) { this.flags = flags; this.stream_length = streamLength; this.xing_header = xingHeader; this.vbri_header = vbriHeader; this.duration = TimeSpan.Zero; }
private AudioHeader(ByteVector data, TagLib.File file, long position) { this.duration = TimeSpan.Zero; this.stream_length = 0L; if (data.Count < 4) { throw new CorruptFileException("Insufficient header length."); } if (data[0] != 0xff) { throw new CorruptFileException("First byte did not match MPEG synch."); } if (((data[1] & 230) <= 0xe0) || ((data[1] & 0x18) == 8)) { throw new CorruptFileException("Second byte did not match MPEG synch."); } this.flags = data.ToUInt(); if (((this.flags >> 12) & 15) == 15) { throw new CorruptFileException("Header uses invalid bitrate index."); } if (((this.flags >> 10) & 3) == 3) { throw new CorruptFileException("Invalid sample rate."); } this.xing_header = TagLib.Mpeg.XingHeader.Unknown; this.vbri_header = TagLib.Mpeg.VBRIHeader.Unknown; file.Seek(position + TagLib.Mpeg.XingHeader.XingHeaderOffset(this.Version, this.ChannelMode)); ByteVector vector = file.ReadBlock(0x10); if ((vector.Count == 0x10) && vector.StartsWith(TagLib.Mpeg.XingHeader.FileIdentifier)) { this.xing_header = new TagLib.Mpeg.XingHeader(vector); } if (!this.xing_header.Present) { file.Seek(position + TagLib.Mpeg.VBRIHeader.VBRIHeaderOffset()); ByteVector vector2 = file.ReadBlock(0x18); if ((vector2.Count == 0x18) && vector2.StartsWith(TagLib.Mpeg.VBRIHeader.FileIdentifier)) { this.vbri_header = new TagLib.Mpeg.VBRIHeader(vector2); } } }
//Additional info here http://gabriel.mp3-tech.org/mp3infotag.html //https://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header /// <summary>See if the mp3 file is encoded using VBR. Not sure what to do with ABR... /// </summary> private bool IsVBR() { bool bVBR = false; if (currentFile.MimeType != "taglib/mp3") { return(false); } foreach (ICodec codec in currentFile.Properties.Codecs) { TagLib.Mpeg.AudioHeader header = (TagLib.Mpeg.AudioHeader)codec; // if (header == null) // return; if (header.XingHeader.Present) { currentFile.Mode = TagLib.File.AccessMode.Read; long XingHeader = currentFile.Find(TagLib.Mpeg.XingHeader.FileIdentifier); long Offset = TagLib.Mpeg.XingHeader.XingHeaderOffset(header.Version, header.ChannelMode); TagLib.Mpeg.XingHeader xing_header = TagLib.Mpeg.XingHeader.Unknown; currentFile.Seek(XingHeader);// + Offset); ByteVector xing_data = currentFile.ReadBlock(16); if (xing_data.Count == 16 && xing_data.StartsWith( TagLib.Mpeg.XingHeader.FileIdentifier)) { xing_header = new TagLib.Mpeg.XingHeader(xing_data); } int Flags = BitConverter.ToInt32(xing_data.Take(8).ToArray().Reverse().ToArray(), 0); bool FramesPresent = (Flags & 0x0001) > 0; bool BytesPresent = (Flags & 0x0002) > 0; bool TOCPresent = (Flags & 0x0004) > 0; bool QualityPresent = (Flags & 0x0008) > 0; long LameHeader = currentFile.Find(LAME_Identifier); if (QualityPresent) { //Header offset + 8 (XING + flags) + Frames, Bytes and TOC if available currentFile.Seek(XingHeader + 8 + 4 * (FramesPresent ? 1 : 0) + 4 * (BytesPresent ? 1 : 0) + 100 * (TOCPresent ? 1 : 0)); ByteVector Quality_data = currentFile.ReadBlock(4); int VBRQuality = BitConverter.ToInt32(Quality_data.ToArray().Reverse().ToArray(), 0); bVBR = true; } currentFile.Mode = TagLib.File.AccessMode.Closed; // if (xing_header.Present) // return false; // var vector = new TagLib.ByteVector(); // TagLib.ByteVector xing = header.; /* CODE HERE */ /* TagLib.File ref(fileName); * TagLib.Mpeg.File *file = dynamic_cast<TagLib.Mpeg.File *>(ref file()); * * if(!file) * return; * * TagLib.Mpeg.Properties *properties = file->audioProperties(); * const TagLib::MPEG::XingHeader *xingHeader = properties->xingHeader(); * * if(!xingHeader) * return; */ } if (header.VBRIHeader.Present) { /* CODE HERE */ } } return(bVBR); }