internal static VorbisMode Init(VorbisStreamDecoder vorbis, DataPacket packet) { var mode = new VorbisMode(vorbis); mode.BlockFlag = packet.ReadBit(); mode.WindowType = (int)packet.ReadBits(16); mode.TransformType = (int)packet.ReadBits(16); var mapping = (int)packet.ReadBits(8); if (mode.WindowType != 0 || mode.TransformType != 0 || mapping >= vorbis.Maps.Length) { throw new InvalidDataException(); } mode.Mapping = vorbis.Maps[mapping]; mode.BlockSize = mode.BlockFlag ? vorbis.Block1Size : vorbis.Block0Size; // now pre-calc the window(s)... if (mode.BlockFlag) { // long block mode._windows = new float[4][]; mode._windows[0] = new float[vorbis.Block1Size]; mode._windows[1] = new float[vorbis.Block1Size]; mode._windows[2] = new float[vorbis.Block1Size]; mode._windows[3] = new float[vorbis.Block1Size]; } else { // short block mode._windows = new float[1][]; mode._windows[0] = new float[vorbis.Block0Size]; } mode.CalcWindows(); return(mode); }
protected override void Init(DataPacket packet) { // this is pretty well stolen directly from libvorbis... BSD license _order = (int)packet.ReadBits(8); _rate = (int)packet.ReadBits(16); _bark_map_size = (int)packet.ReadBits(16); _ampBits = (int)packet.ReadBits(6); _ampOfs = (int)packet.ReadBits(8); _books = new VorbisCodebook[(int)packet.ReadBits(4) + 1]; if (_order < 1 || _rate < 1 || _bark_map_size < 1 || _books.Length == 0) { throw new InvalidDataException(); } _ampDiv = (1 << _ampBits) - 1; for (var i = 0; i < _books.Length; i++) { var num = (int)packet.ReadBits(8); if (num < 0 || num >= _vorbis.Books.Length) { throw new InvalidDataException(); } var book = _vorbis.Books[num]; if (book.MapType == 0 || book.Dimensions < 1) { throw new InvalidDataException(); } _books[i] = book; } _bookBits = Utils.ilog(_books.Length); _barkMaps = new Dictionary <int, int[]>(); _barkMaps[_vorbis.Block0Size] = SynthesizeBarkCurve(_vorbis.Block0Size / 2); _barkMaps[_vorbis.Block1Size] = SynthesizeBarkCurve(_vorbis.Block1Size / 2); _wMap = new Dictionary <int, float[]>(); _wMap[_vorbis.Block0Size] = SynthesizeWDelMap(_vorbis.Block0Size / 2); _wMap[_vorbis.Block1Size] = SynthesizeWDelMap(_vorbis.Block1Size / 2); _reusablePacketData = new PacketData0[_vorbis._channels]; for (var i = 0; i < _reusablePacketData.Length; i++) { _reusablePacketData[i] = new PacketData0() { Coeff = new float[_order + 1] }; } }
internal static VorbisTime Init(VorbisStreamDecoder vorbis, DataPacket packet) { var type = (int)packet.ReadBits(16); VorbisTime time = null; switch (type) { case 0: time = new Time0(vorbis); break; } if (time == null) { throw new InvalidDataException(); } time.Init(packet); return(time); }
internal static VorbisMapping Init(VorbisStreamDecoder vorbis, DataPacket packet) { var type = (int)packet.ReadBits(16); VorbisMapping mapping = null; switch (type) { case 0: mapping = new Mapping0(vorbis); break; } if (mapping == null) { throw new InvalidDataException(); } mapping.Init(packet); return(mapping); }
internal static VorbisFloor Init(VorbisStreamDecoder vorbis, DataPacket packet) { var type = (int)packet.ReadBits(16); VorbisFloor floor = null; switch (type) { case 0: floor = new Floor0(vorbis); break; case 1: floor = new Floor1(vorbis); break; } if (floor == null) { throw new InvalidDataException(); } floor.Init(packet); return(floor); }
internal static VorbisResidue Init(VorbisStreamDecoder vorbis, DataPacket packet) { var type = (int)packet.ReadBits(16); VorbisResidue residue = null; switch (type) { case 0: residue = new Residue0(vorbis); break; case 1: residue = new Residue1(vorbis); break; case 2: residue = new Residue2(vorbis); break; } if (residue == null) { throw new InvalidDataException(); } residue.Init(packet); return(residue); }
internal int GetPacketLength(DataPacket curPacket, DataPacket lastPacket) { // if we don't have a previous packet, or we're re-syncing, this packet has no audio data to return if (lastPacket == null || curPacket.IsResync) { return(0); } // make sure they are audio packets if (curPacket.ReadBit()) { return(0); } if (lastPacket.ReadBit()) { return(0); } // get the current packet's information var modeIdx = (int)curPacket.ReadBits(_modeFieldBits); if (modeIdx < 0 || modeIdx >= Modes.Length) { return(0); } var mode = Modes[modeIdx]; // get the last packet's information modeIdx = (int)lastPacket.ReadBits(_modeFieldBits); if (modeIdx < 0 || modeIdx >= Modes.Length) { return(0); } var prevMode = Modes[modeIdx]; // now calculate the totals... return(mode.BlockSize / 4 + prevMode.BlockSize / 4); }
private void InitTree(DataPacket packet) { bool sparse; var total = 0; if (packet.ReadBit()) { // ordered var len = (int)packet.ReadBits(5) + 1; for (var i = 0; i < Entries;) { var cnt = (int)packet.ReadBits(Utils.ilog(Entries - i)); while (--cnt >= 0) { Lengths[i++] = len; } ++len; } total = 0; sparse = false; } else { // unordered sparse = packet.ReadBit(); for (var i = 0; i < Entries; i++) { if (!sparse || packet.ReadBit()) { Lengths[i] = (int)packet.ReadBits(5) + 1; ++total; } else { // mark the entry as unused Lengths[i] = -1; } } } // figure out the maximum bit size; if all are unused, don't do anything else if ((MaxBits = Lengths.Max()) > -1) { var sortedCount = 0; int[] codewordLengths = null; if (sparse && total >= Entries >> 2) { codewordLengths = new int[Entries]; Array.Copy(Lengths, codewordLengths, Entries); sparse = false; } // compute size of sorted tables if (sparse) { sortedCount = total; } else { sortedCount = 0; } var sortedEntries = sortedCount; int[] values = null; int[] codewords = null; if (!sparse) { codewords = new int[Entries]; } else if (sortedEntries != 0) { codewordLengths = new int[sortedEntries]; codewords = new int[sortedEntries]; values = new int[sortedEntries]; } if (!ComputeCodewords(sparse, sortedEntries, codewords, codewordLengths, len: Lengths, n: Entries, values: values)) { throw new InvalidDataException(); } PrefixList = Huffman.BuildPrefixedLinkedList(values ?? Enumerable.Range(0, codewords.Length).ToArray(), codewordLengths ?? Lengths, codewords, out PrefixBitLength, out PrefixOverflowTree); } }
private void InitLookupTable(DataPacket packet) { MapType = (int)packet.ReadBits(4); if (MapType == 0) { return; } var minValue = Utils.ConvertFromVorbisFloat32(packet.ReadUInt32()); var deltaValue = Utils.ConvertFromVorbisFloat32(packet.ReadUInt32()); var valueBits = (int)packet.ReadBits(4) + 1; var sequence_p = packet.ReadBit(); var lookupValueCount = Entries * Dimensions; var lookupTable = new float[lookupValueCount]; if (MapType == 1) { lookupValueCount = lookup1_values(); } var multiplicands = new uint[lookupValueCount]; for (var i = 0; i < lookupValueCount; i++) { multiplicands[i] = (uint)packet.ReadBits(valueBits); } // now that we have the initial data read in, calculate the entry tree if (MapType == 1) { for (var idx = 0; idx < Entries; idx++) { var last = 0.0; var idxDiv = 1; for (var i = 0; i < Dimensions; i++) { var moff = (idx / idxDiv) % lookupValueCount; var value = (float)multiplicands[moff] * deltaValue + minValue + last; lookupTable[idx * Dimensions + i] = (float)value; if (sequence_p) { last = value; } idxDiv *= lookupValueCount; } } } else { for (var idx = 0; idx < Entries; idx++) { var last = 0.0; var moff = idx * Dimensions; for (var i = 0; i < Dimensions; i++) { var value = multiplicands[moff] * deltaValue + minValue + last; lookupTable[idx * Dimensions + i] = (float)value; if (sequence_p) { last = value; } ++moff; } } } LookupTable = lookupTable; }
protected override void Init(DataPacket packet) { _partitionClass = new int[(int)packet.ReadBits(5)]; for (var i = 0; i < _partitionClass.Length; i++) { _partitionClass[i] = (int)packet.ReadBits(4); } var maximum_class = _partitionClass.Max(); _classDimensions = new int[maximum_class + 1]; _classSubclasses = new int[maximum_class + 1]; _classMasterbooks = new VorbisCodebook[maximum_class + 1]; _classMasterBookIndex = new int[maximum_class + 1]; _subclassBooks = new VorbisCodebook[maximum_class + 1][]; _subclassBookIndex = new int[maximum_class + 1][]; for (var i = 0; i <= maximum_class; i++) { _classDimensions[i] = (int)packet.ReadBits(3) + 1; _classSubclasses[i] = (int)packet.ReadBits(2); if (_classSubclasses[i] > 0) { _classMasterBookIndex[i] = (int)packet.ReadBits(8); _classMasterbooks[i] = _vorbis.Books[_classMasterBookIndex[i]]; } _subclassBooks[i] = new VorbisCodebook[1 << _classSubclasses[i]]; _subclassBookIndex[i] = new int[_subclassBooks[i].Length]; for (var j = 0; j < _subclassBooks[i].Length; j++) { var bookNum = (int)packet.ReadBits(8) - 1; if (bookNum >= 0) { _subclassBooks[i][j] = _vorbis.Books[bookNum]; } _subclassBookIndex[i][j] = bookNum; } } _multiplier = (int)packet.ReadBits(2); _range = _rangeLookup[_multiplier]; _yBits = _yBitsLookup[_multiplier]; ++_multiplier; var rangeBits = (int)packet.ReadBits(4); var xList = new List <int>(); xList.Add(0); xList.Add(1 << rangeBits); for (var i = 0; i < _partitionClass.Length; i++) { var classNum = _partitionClass[i]; for (var j = 0; j < _classDimensions[classNum]; j++) { xList.Add((int)packet.ReadBits(rangeBits)); } } _xList = xList.ToArray(); // precalc the low and high neighbors (and init the sort table) _lNeigh = new int[xList.Count]; _hNeigh = new int[xList.Count]; _sortIdx = new int[xList.Count]; _sortIdx[0] = 0; _sortIdx[1] = 1; for (var i = 2; i < _lNeigh.Length; i++) { _lNeigh[i] = 0; _hNeigh[i] = 1; _sortIdx[i] = i; for (var j = 2; j < i; j++) { var temp = _xList[j]; if (temp < _xList[i]) { if (temp > _xList[_lNeigh[i]]) { _lNeigh[i] = j; } } else { if (temp < _xList[_hNeigh[i]]) { _hNeigh[i] = j; } } } } // precalc the sort table for (var i = 0; i < _sortIdx.Length - 1; i++) { for (var j = i + 1; j < _sortIdx.Length; j++) { if (_xList[i] == _xList[j]) { throw new InvalidDataException(); } if (_xList[_sortIdx[i]] > _xList[_sortIdx[j]]) { // swap the sort indexes var temp = _sortIdx[i]; _sortIdx[i] = _sortIdx[j]; _sortIdx[j] = temp; } } } // pre-create our packet data instances _reusablePacketData = new PacketData1[_vorbis._channels]; for (var i = 0; i < _reusablePacketData.Length; i++) { _reusablePacketData[i] = new PacketData1(); } }
protected override void Init(DataPacket packet) { var submapCount = 1; if (packet.ReadBit()) { submapCount += (int)packet.ReadBits(4); } // square polar mapping var couplingSteps = 0; if (packet.ReadBit()) { couplingSteps = (int)packet.ReadBits(8) + 1; } var couplingBits = Utils.ilog(_vorbis._channels - 1); CouplingSteps = new CouplingStep[couplingSteps]; for (var j = 0; j < couplingSteps; j++) { var magnitude = (int)packet.ReadBits(couplingBits); var angle = (int)packet.ReadBits(couplingBits); if (magnitude == angle || magnitude > _vorbis._channels - 1 || angle > _vorbis._channels - 1) { throw new InvalidDataException(); } CouplingSteps[j] = new CouplingStep { Angle = angle, Magnitude = magnitude }; } // reserved bits if (packet.ReadBits(2) != 0UL) { throw new InvalidDataException(); } // channel multiplex var mux = new int[_vorbis._channels]; if (submapCount > 1) { for (var c = 0; c < ChannelSubmap.Length; c++) { mux[c] = (int)packet.ReadBits(4); if (mux[c] >= submapCount) { throw new InvalidDataException(); } } } // submaps Submaps = new Submap[submapCount]; for (var j = 0; j < submapCount; j++) { packet.ReadBits(8); // unused placeholder var floorNum = (int)packet.ReadBits(8); if (floorNum >= _vorbis.Floors.Length) { throw new InvalidDataException(); } var residueNum = (int)packet.ReadBits(8); if (residueNum >= _vorbis.Residues.Length) { throw new InvalidDataException(); } Submaps[j] = new Submap { Floor = _vorbis.Floors[floorNum], Residue = _vorbis.Residues[floorNum] }; } ChannelSubmap = new Submap[_vorbis._channels]; for (var c = 0; c < ChannelSubmap.Length; c++) { ChannelSubmap[c] = Submaps[mux[c]]; } }
private bool UnpackPacket(DataPacket packet) { // make sure we're on an audio packet if (packet.ReadBit()) { // we really can't do anything... count the bits as waste return(false); } // get mode and prev/next flags var modeBits = _modeFieldBits; _mode = Modes[(int)packet.ReadBits(_modeFieldBits)]; if (_mode.BlockFlag) { _prevFlag = packet.ReadBit(); _nextFlag = packet.ReadBit(); modeBits += 2; } else { _prevFlag = _nextFlag = false; } if (packet.IsShort) { return(false); } var startBits = packet.BitsRead; var halfBlockSize = _mode.BlockSize / 2; // read the noise floor data (but don't decode yet) for (var i = 0; i < _channels; i++) { _floorData[i] = _mode.Mapping.ChannelSubmap[i].Floor.UnpackPacket(packet, _mode.BlockSize, i); _noExecuteChannel[i] = !_floorData[i].ExecuteChannel; // go ahead and clear the residue buffers Array.Clear(_residue[i], 0, halfBlockSize); } // make sure we handle no-energy channels correctly given the couplings... foreach (var step in _mode.Mapping.CouplingSteps) { if (_floorData[step.Angle].ExecuteChannel || _floorData[step.Magnitude].ExecuteChannel) { _floorData[step.Angle].ForceEnergy = true; _floorData[step.Magnitude].ForceEnergy = true; } } var floorBits = packet.BitsRead - startBits; startBits = packet.BitsRead; foreach (var subMap in _mode.Mapping.Submaps) { for (var j = 0; j < _channels; j++) { if (_mode.Mapping.ChannelSubmap[j] != subMap) { _floorData[j].ForceNoEnergy = true; } } var rTemp = subMap.Residue.Decode(packet, _noExecuteChannel, _channels, _mode.BlockSize); for (var c = 0; c < _channels; c++) { var r = _residue[c]; var rt = rTemp[c]; for (var i = 0; i < halfBlockSize; i++) { r[i] += rt[i]; } } } _glueBits += 1; _modeBits += modeBits; _floorBits += floorBits; _resBits += packet.BitsRead - startBits; _wasteBits += 8 * packet.Length - packet.BitsRead; _packetCount += 1; return(true); }
private bool LoadBooks(DataPacket packet) { if (!packet.ReadBytes(7).SequenceEqual(new byte[] { 0x05, 0x76, 0x6f, 0x72, 0x62, 0x69, 0x73 })) { return(false); } if (!_pagesSeen.Contains((_lastPageSeen = packet.PageSequenceNumber))) { _pagesSeen.Add(_lastPageSeen); } var bits = packet.BitsRead; _glueBits += packet.BitsRead; // get books Books = new VorbisCodebook[packet.ReadByte() + 1]; for (var i = 0; i < Books.Length; i++) { Books[i] = VorbisCodebook.Init(this, packet, i); } _bookBits += packet.BitsRead - bits; bits = packet.BitsRead; // get times Times = new VorbisTime[(int)packet.ReadBits(6) + 1]; for (var i = 0; i < Times.Length; i++) { Times[i] = VorbisTime.Init(this, packet); } _timeHdrBits += packet.BitsRead - bits; bits = packet.BitsRead; // get floor Floors = new VorbisFloor[(int)packet.ReadBits(6) + 1]; for (var i = 0; i < Floors.Length; i++) { Floors[i] = VorbisFloor.Init(this, packet); } _floorHdrBits += packet.BitsRead - bits; bits = packet.BitsRead; // get residue Residues = new VorbisResidue[(int)packet.ReadBits(6) + 1]; for (var i = 0; i < Residues.Length; i++) { Residues[i] = VorbisResidue.Init(this, packet); } _resHdrBits += packet.BitsRead - bits; bits = packet.BitsRead; // get map Maps = new VorbisMapping[(int)packet.ReadBits(6) + 1]; for (var i = 0; i < Maps.Length; i++) { Maps[i] = VorbisMapping.Init(this, packet); } _mapHdrBits += packet.BitsRead - bits; bits = packet.BitsRead; // get mode settings Modes = new VorbisMode[(int)packet.ReadBits(6) + 1]; for (var i = 0; i < Modes.Length; i++) { Modes[i] = VorbisMode.Init(this, packet); } _modeHdrBits += packet.BitsRead - bits; // check the framing bit if (!packet.ReadBit()) { throw new InvalidDataException(); } ++_glueBits; _wasteHdrBits += 8 * packet.Length - packet.BitsRead; _modeFieldBits = Utils.ilog(Modes.Length - 1); return(true); }
protected override void Init(DataPacket packet) { // this is pretty well stolen directly from libvorbis... BSD license _begin = (int)packet.ReadBits(24); _end = (int)packet.ReadBits(24); _partitionSize = (int)packet.ReadBits(24) + 1; _classifications = (int)packet.ReadBits(6) + 1; _classBook = _vorbis.Books[(int)packet.ReadBits(8)]; _cascade = new int[_classifications]; var acc = 0; for (var i = 0; i < _classifications; i++) { var low_bits = (int)packet.ReadBits(3); if (packet.ReadBit()) { _cascade[i] = (int)packet.ReadBits(5) << 3 | low_bits; } else { _cascade[i] = low_bits; } acc += icount(_cascade[i]); } var bookNums = new int[acc]; for (var i = 0; i < acc; i++) { bookNums[i] = (int)packet.ReadBits(8); if (_vorbis.Books[bookNums[i]].MapType == 0) { throw new InvalidDataException(); } } var entries = _classBook.Entries; var dim = _classBook.Dimensions; var partvals = 1; while (dim > 0) { partvals *= _classifications; if (partvals > entries) { throw new InvalidDataException(); } --dim; } // now the lookups dim = _classBook.Dimensions; _books = new VorbisCodebook[_classifications][]; acc = 0; var maxstage = 0; int stages; for (var j = 0; j < _classifications; j++) { stages = Utils.ilog(_cascade[j]); _books[j] = new VorbisCodebook[stages]; if (stages > 0) { maxstage = Math.Max(maxstage, stages); for (var k = 0; k < stages; k++) { if ((_cascade[j] & (1 << k)) > 0) { _books[j][k] = _vorbis.Books[bookNums[acc++]]; } } } } _maxStages = maxstage; _decodeMap = new int[partvals][]; for (var j = 0; j < partvals; j++) { var val = j; var mult = partvals / _classifications; _decodeMap[j] = new int[_classBook.Dimensions]; for (var k = 0; k < _classBook.Dimensions; k++) { var deco = val / mult; val -= deco * mult; mult /= _classifications; _decodeMap[j][k] = deco; } } _entryCache = new int[_partitionSize]; _partWordCache = new int[_vorbis._channels][][]; var maxPartWords = ((_end - _begin) / _partitionSize + _classBook.Dimensions - 1) / _classBook.Dimensions; for (var ch = 0; ch < _vorbis._channels; ch++) { _partWordCache[ch] = new int[maxPartWords][]; } }