// https://www.xiph.org/vorbis/doc/libvorbis/vorbis_packet_blocksize.html public int PacketBlockSize(OggPacket op) { using (var input = new OggBitStream(op)) { // Check the packet type if (input.ReadBits(1) != 0) { throw new InvalidDataException("Not an audio data packet."); } int modebits = 0; for (int v = CodecSetup.Modes; v > 1; v >>= 1) { modebits++; } // read our mode and pre/post windowsize int mode = input.ReadBits(modebits); if (-1 == mode) { throw new InvalidDataException("Invalid Ogg/Vorbis packet."); } return(CodecSetup.BlockSizes[CodecSetup.ModeParam[mode].BlockFlag]); } }
VorbisInfoFloor UnpackFloor0(OggBitStream input) { var info = new VorbisInfoFloor(); int order = input.ReadBits(8); int rate = input.ReadBits(16); int barkmap = input.ReadBits(16); int ampbits = input.ReadBits(6); int ampdB = input.ReadBits(8); int numbooks = input.ReadBits(4) + 1; if (order < 1 || rate < 1 || barkmap < 1 || numbooks < 1) { return(null); } for (int j = 0; j < numbooks; ++j) { int books = input.ReadByte(); if (books < 0 || books >= CodecSetup.Books) { return(null); } } return(info); }
void UnpackInfo(OggBitStream input) { Version = input.ReadInt32(); if (Version != 0) { throw new InvalidDataException("Invalid Vorbis encoder version."); } Channels = input.ReadUInt8(); Rate = input.ReadInt32(); BitrateUpper = input.ReadInt32(); BitrateNominal = input.ReadInt32(); BitrateLower = input.ReadInt32(); CodecSetup.BlockSizes[0] = 1 << input.ReadBits(4); CodecSetup.BlockSizes[1] = 1 << input.ReadBits(4); if (input.ReadBits(1) != 1) { throw InvalidHeader(); } }
internal void UnpackComment(OggBitStream input) { int vendor_len = input.ReadInt32(); if (vendor_len < 0) { throw VorbisInfo.InvalidHeader(); } var vendor = input.ReadBytes(vendor_len); int count = input.ReadInt32(); if (count < 0) { throw VorbisInfo.InvalidHeader(); } var comments = new List <byte[]> (count); for (int i = 0; i < count; ++i) { int len = input.ReadInt32(); if (len < 0) { throw VorbisInfo.InvalidHeader(); } var bytes = input.ReadBytes(len); comments.Add(bytes); } if (input.ReadBits(1) != 1) { throw VorbisInfo.InvalidHeader(); } this.Vendor = vendor; this.Comments = comments; }
VorbisInfoMapping UnpackMapping(OggBitStream input) { var info = new VorbisInfoMapping(); int b = input.ReadBits(1); if (b < 0) { return(null); } if (b > 0) { info.submaps = input.ReadBits(4) + 1; if (info.submaps <= 0) { return(null); } } else { info.submaps = 1; } b = input.ReadBits(1); if (b < 0) { return(null); } if (b > 0) { info.coupling_steps = input.ReadBits(8) + 1; if (info.coupling_steps <= 0) { return(null); } for (int i = 0; i < info.coupling_steps; ++i) { int bits = CountBits((uint)Channels); int testM = input.ReadBits(bits); int testA = input.ReadBits(bits); if (testM < 0 || testA < 0 || testM == testA || testM >= Channels || testA >= Channels) { return(null); } } } if (input.ReadBits(2) != 0) { return(null); } if (info.submaps > 1) { for (int i = 0; i < Channels; ++i) { int chmuxlist = input.ReadBits(4); if (chmuxlist >= info.submaps || chmuxlist < 0) { return(null); } } } for (int i = 0; i < info.submaps; ++i) { input.ReadByte(); // time submap unused int floorsubmap = input.ReadByte(); if (floorsubmap >= CodecSetup.Floors || floorsubmap < 0) { return(null); } int residuesubmap = input.ReadByte(); if (residuesubmap >= CodecSetup.Residues || residuesubmap < 0) { return(null); } } return(info); }
object UnpackResidue(OggBitStream input) { var info = new VorbisInfoResidue(); info.begin = input.ReadBits(24); info.end = input.ReadBits(24); info.grouping = input.ReadBits(24) + 1; info.partitions = input.ReadBits(6) + 1; info.groupbook = input.ReadBits(8); // check for premature EOP if (info.groupbook < 0) { return(null); } int acc = 0; for (int j = 0; j < info.partitions; ++j) { int cascade = input.ReadBits(3); int cflag = input.ReadBits(1); if (cflag < 0) { return(null); } if (cflag > 0) { int c = input.ReadBits(5); if (c < 0) { return(null); } cascade |= c << 3; } // info.secondstages[j] = cascade; acc += CountSetBits((uint)cascade); } for (int j = 0; j < acc; ++j) { int book = input.ReadBits(8); if (book < 0) { return(null); } if (book >= CodecSetup.Books) { return(null); } // if (CodecSetup.book_param[book].maptype == 0) return null; // info.booklist[j] = book; } if (info.groupbook >= CodecSetup.Books) { return(null); } /* * int entries = CodecSetup.book_param[info.groupbook].entries; * int dim = CodecSetup.book_param[info.groupbook].dim; * int partvals = 1; * if (dim < 1) * return null; * while (dim > 0) * { * partvals *= info.partitions; * if (partvals > entries) * return null; * dim--; * } * info.partvals = partvals; */ return(info); }
VorbisInfoFloor UnpackFloor1(OggBitStream input) { int max_class = -1; var info = new VorbisInfoFloor(); // read partitions int partitions = input.ReadBits(5); // only 0 to 31 legal var partition_class = new int[partitions]; for (int j = 0; j < partitions; ++j) { partition_class[j] = input.ReadBits(4); // only 0 to 15 legal if (partition_class[j] < 0) { return(null); } if (max_class < partition_class[j]) { max_class = partition_class[j]; } } // read partition classes var class_dim = new int[max_class + 1]; for (int j = 0; j < max_class + 1; ++j) { class_dim[j] = input.ReadBits(3) + 1; // 1 to 8 int class_subs = input.ReadBits(2); // 0,1,2,3 bits if (class_subs < 0) { return(null); } if (class_subs > 0) { input.ReadBits(8); // class_book } for (int k = 0; k < (1 << class_subs); ++k) { int class_subbook = input.ReadBits(8) - 1; // info.class_subbook[j][k] } } // read the post list int mult = input.ReadBits(2) + 1; // only 1,2,3,4 legal now int rangebits = input.ReadBits(4); if (rangebits < 0) { return(null); } int count = 0; // var postlist = new int[VorbisInfoFloor.Posit + 2]; for (int j = 0, k = 0; j < partitions; ++j) { count += class_dim[partition_class[j]]; if (count > VorbisInfoFloor.Posit) { return(null); } for (; k < count; ++k) { int t = input.ReadBits(rangebits); if (t < 0 || t >= (1 << rangebits)) { return(null); } // postlist[k+2] = t; } } // postlist[0] = 0; // postlist[1] = 1<<rangebits; // don't allow repeated values in post list as they'd result in // zero-length segments /* * var indices = Enumerable.Range (0, count+2).OrderBy (i => postlist[i]).ToArray(); * for (int j = 1; j < count+2; j++) * if(postlist[indices[j-1]] == postlist[indices[j]]) * return null; */ return(info); }
StaticCodebook StaticBookUnpack(OggBitStream input) { // make sure alignment is correct if (input.ReadBits(24) != 0x564342) { return(null); } var s = new StaticCodebook(); // first the basic parameters s.dim = input.ReadBits(16); s.entries = input.ReadBits(24); if (-1 == s.entries) { return(null); } if (iLog((uint)s.dim) + iLog((uint)s.entries) > 24) { return(null); } // codeword ordering.... length ordered or unordered? switch (input.ReadBits(1)) { case 0: // allocated but unused entries? int unused = input.ReadBits(1); // unordered s.lengthlist = new byte[s.entries]; // allocated but unused entries? if (unused > 0) { // yes, unused entries for (int i = 0; i < s.entries; ++i) { if (input.ReadBits(1) > 0) { int num = input.ReadBits(5); if (-1 == num) { return(null); } s.lengthlist[i] = (byte)(num + 1); } else { s.lengthlist[i] = 0; } } } else { // all entries used; no tagging for (int i = 0; i < s.entries; ++i) { int num = input.ReadBits(5); if (-1 == num) { return(null); } s.lengthlist[i] = (byte)(num + 1); } } break; case 1: // ordered int length = input.ReadBits(5) + 1; if (0 == length) { return(null); } s.lengthlist = new byte[s.entries]; for (int i = 0; i < s.entries;) { int num = input.ReadBits(iLog((uint)(s.entries - i))); if (-1 == num || length > 32 || num > s.entries - i || (num > 0 && ((num - 1) >> (length - 1)) > 1)) { return(null); } for (int j = 0; j < num; ++j, ++i) { s.lengthlist[i] = (byte)length; } length++; } break; default: return(null); } // Do we have a mapping to unpack? switch ((s.maptype = input.ReadBits(4))) { case 0: // no mapping break; case 1: case 2: // implicitly populated value mapping // explicitly populated value mapping s.q_min = input.ReadInt32(); s.q_delta = input.ReadInt32(); s.q_quant = input.ReadBits(4) + 1; s.q_sequencep = input.ReadBits(1); if (-1 == s.q_sequencep) { return(null); } int quantvals = 0; switch (s.maptype) { case 1: quantvals = s.dim == 0 ? 0 : s.Maptype1Quantvals(); break; case 2: quantvals = s.entries * s.dim; break; } // quantized values s.quantlist = new int[quantvals]; for (int i = 0; i < quantvals; ++i) { s.quantlist[i] = input.ReadBits(s.q_quant); } if (quantvals > 0 && s.quantlist[quantvals - 1] == -1) { return(null); } break; default: // EOF return(null); } // all set return(s); }
void UnpackBooks(OggBitStream input) { // codebooks CodecSetup.Books = input.ReadUInt8() + 1; if (CodecSetup.Books <= 0) { throw InvalidHeader(); } for (int i = 0; i < CodecSetup.Books; ++i) { var param = StaticBookUnpack(input); if (null == param) { throw InvalidHeader(); } CodecSetup.BookParam[i] = param; } // time backend settings; hooks are unused int times = input.ReadBits(6) + 1; if (times <= 0) { throw InvalidHeader(); } for (int i = 0; i < times; ++i) { int test = input.ReadBits(16); if (test < 0 || test >= TimeB) { throw InvalidHeader(); } } // floor backend settings CodecSetup.Floors = input.ReadBits(6) + 1; if (CodecSetup.Floors <= 0) { throw InvalidHeader(); } for (int i = 0; i < CodecSetup.Floors; i++) { int floor_type = input.ReadBits(16); if (floor_type < 0 || floor_type >= FloorB) { throw InvalidHeader(); } CodecSetup.FloorType[i] = floor_type; var param = FloorMethods[floor_type] (input); if (null == param) { throw InvalidHeader(); } CodecSetup.FloorParam[i] = param; } // residue backend settings CodecSetup.Residues = input.ReadBits(6) + 1; if (CodecSetup.Residues <= 0) { throw InvalidHeader(); } for (int i = 0; i < CodecSetup.Residues; ++i) { int residue_type = input.ReadBits(16); if (residue_type < 0 || residue_type >= ResB) { throw InvalidHeader(); } CodecSetup.ResidueType[i] = residue_type; var param = UnpackResidue(input); if (null == param) { throw InvalidHeader(); } CodecSetup.ResidueParam[i] = param; } // map backend settings CodecSetup.Maps = input.ReadBits(6) + 1; if (CodecSetup.Maps <= 0) { throw InvalidHeader(); } for (int i = 0; i < CodecSetup.Maps; ++i) { int map_type = input.ReadBits(16); if (map_type < 0 || map_type >= MapB) { throw InvalidHeader(); } CodecSetup.MapType[i] = map_type; var param = UnpackMapping(input); if (null == param) { throw InvalidHeader(); } CodecSetup.MapParam[i] = param; } // mode settings CodecSetup.Modes = input.ReadBits(6) + 1; if (CodecSetup.Modes <= 0) { throw InvalidHeader(); } for (int i = 0; i < CodecSetup.Modes; ++i) { CodecSetup.ModeParam[i].BlockFlag = input.ReadBits(1); CodecSetup.ModeParam[i].WindowType = input.ReadBits(16); CodecSetup.ModeParam[i].TransformType = input.ReadBits(16); CodecSetup.ModeParam[i].Mapping = input.ReadBits(8); if (CodecSetup.ModeParam[i].WindowType >= WindowB || CodecSetup.ModeParam[i].TransformType >= WindowB || CodecSetup.ModeParam[i].Mapping >= CodecSetup.Maps || CodecSetup.ModeParam[i].Mapping < 0) { throw InvalidHeader(); } } if (input.ReadBits(1) != 1) { throw InvalidHeader(); } }