Beispiel #1
0
            internal override PacketData UnpackPacket(DataPacket packet, int blockSize, int channel)
            {
                var data = _reusablePacketData[channel];

                data.BlockSize     = blockSize;
                data.ForceEnergy   = false;
                data.ForceNoEnergy = false;

                data.Amp = packet.ReadUBits(_ampBits);
                if (data.Amp > 0f)
                {
                    // this is pretty well stolen directly from libvorbis...  BSD license
                    Array.Clear(data.Coeff, 0, data.Coeff.Length);

                    data.Amp = data.Amp / _ampDiv * _ampOfs;

                    uint bookNum = (uint)packet.ReadUBits(_bookBits);
                    if (bookNum >= _books.Length)
                    {
                        // we ran out of data or the packet is corrupt...  0 the floor and return
                        data.Amp = 0;
                        return(data);
                    }
                    VorbisCodebook book = _books[bookNum];

                    // first, the book decode...
                    for (int i = 0; i < _order;)
                    {
                        int entry = book.DecodeScalar(packet);
                        if (entry == -1)
                        {
                            // we ran out of data or the packet is corrupt...  0 the floor and return
                            data.Amp = 0;
                            return(data);
                        }

                        for (int j = 0; i < _order && j < book.Dimensions; j++, i++)
                        {
                            data.Coeff[i] = book[entry, j];
                        }
                    }

                    // then, the "averaging"
                    float last = 0f;
                    for (int j = 0; j < _order;)
                    {
                        for (int k = 0; j < _order && k < book.Dimensions; j++, k++)
                        {
                            data.Coeff[j] += last;
                        }

                        last = data.Coeff[j - 1];
                    }
                }
                return(data);
            }
Beispiel #2
0
            internal override PacketData UnpackPacket(DataPacket packet, int blockSize, int channel)
            {
                var data = _reusablePacketData[channel];

                data.BlockSize     = blockSize;
                data.ForceEnergy   = false;
                data.ForceNoEnergy = false;
                data.PostCount     = 0;
                Array.Clear(data.Posts, 0, 64);

                // hoist ReadPosts to here since that's all we're doing...
                if (packet.ReadBit())
                {
                    var postCount = 2;
                    data.Posts[0] = (int)packet.ReadUBits(_yBits);
                    data.Posts[1] = (int)packet.ReadUBits(_yBits);

                    for (int i = 0; i < _partitionClass.Length; i++)
                    {
                        var clsNum = _partitionClass[i];
                        var cdim   = _classDimensions[clsNum];
                        var cbits  = _classSubclasses[clsNum];
                        var csub   = (1 << cbits) - 1;
                        var cval   = 0U;
                        if (cbits > 0)
                        {
                            if ((cval = (uint)_classMasterBooks[clsNum].DecodeScalar(packet)) == uint.MaxValue)
                            {
                                // we read a bad value...  bail
                                postCount = 0;
                                break;
                            }
                        }
                        for (int j = 0; j < cdim; j++)
                        {
                            var book = _subclassBooks[clsNum][cval & csub];
                            cval >>= cbits;
                            if (book != null)
                            {
                                if ((data.Posts[postCount] = book.DecodeScalar(packet)) == -1)
                                {
                                    // we read a bad value... bail
                                    postCount = 0;
                                    i         = _partitionClass.Length;
                                    break;
                                }
                            }
                            ++postCount;
                        }
                    }
                    data.PostCount = postCount;
                }

                return(data);
            }
        bool ProcessStreamHeader(DataPacket packet)
        {
            if (!CheckForHeader(packet, streamHeader))
            {
                // don't mark the packet as done... it might be used elsewhere
                _glueBits += packet.Length * 8;
                return(false);
            }

            if (!_pagesSeen.Contains(_lastPageSeen = packet.PageSequenceNumber))
            {
                _pagesSeen.Add(_lastPageSeen);
            }

            _glueBits += 56;

            long startPos = packet.BitsRead;

            if (packet.ReadInt32() != 0)
            {
                throw new InvalidDataException("Only Vorbis stream version 0 is supported.");
            }

            _channels       = packet.ReadByte();
            _sampleRate     = packet.ReadInt32();
            _upperBitrate   = packet.ReadInt32();
            _nominalBitrate = packet.ReadInt32();
            _lowerBitrate   = packet.ReadInt32();

            Block0Size = 1 << (int)packet.ReadUBits(4);
            Block1Size = 1 << (int)packet.ReadUBits(4);

            if (_nominalBitrate == 0)
            {
                if (_upperBitrate > 0 && _lowerBitrate > 0)
                {
                    _nominalBitrate = (_upperBitrate + _lowerBitrate) / 2;
                }
            }

            _metaBits     += packet.BitsRead - startPos + 8;
            _wasteHdrBits += 8 * packet.Length - packet.BitsRead;

            return(true);
        }
        internal void Init(DataPacket packet)
        {
            // first, check the sync pattern
            ulong chkVal = packet.ReadUBits(24);

            if (chkVal != 0x564342UL)
            {
                throw new InvalidDataException();
            }

            // get the counts
            Dimensions = (int)packet.ReadUBits(16);
            Entries    = (int)packet.ReadUBits(24);

            // init the storage
            Lengths = new int[Entries];

            InitTree(packet);
            InitLookupTable(packet);
        }
        public static VorbisMode Init(VorbisStreamDecoder vorbis, DataPacket packet)
        {
            var mode = new VorbisMode(vorbis);

            mode.BlockFlag     = packet.ReadBit();
            mode.WindowType    = (int)packet.ReadUBits(16);
            mode.TransformType = (int)packet.ReadUBits(16);
            var mapping = (int)packet.ReadUBits(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);
        }
Beispiel #6
0
        internal static VorbisTime Init(VorbisStreamDecoder vorbis, DataPacket packet)
        {
            var type = (int)packet.ReadUBits(16);

            VorbisTime time = null;

            switch (type)
            {
            case 0: time = new Time0(vorbis); break;
            }
            if (time == null)
            {
                throw new InvalidDataException();
            }

            time.Init(packet);
            return(time);
        }
Beispiel #7
0
        internal static VorbisMapping Create(VorbisStreamDecoder vorbis, DataPacket packet)
        {
            int type = (int)packet.ReadUBits(16);

            VorbisMapping mapping = null;

            switch (type)
            {
            case 0:
                mapping = new Mapping0(vorbis);
                break;
            }

            if (mapping == null)
            {
                throw new InvalidDataException();
            }

            mapping.Init(packet);
            return(mapping);
        }
Beispiel #8
0
        internal static VorbisResidue Init(VorbisStreamDecoder vorbis, DataPacket packet)
        {
            var type = (int)packet.ReadUBits(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
            int modeIndex = (int)curPacket.ReadUBits(_modeFieldBits);

            if (modeIndex < 0 || modeIndex >= Modes.Length)
            {
                return(0);
            }
            var mode = Modes[modeIndex];

            // get the last packet's information
            modeIndex = (int)lastPacket.ReadUBits(_modeFieldBits);
            if (modeIndex < 0 || modeIndex >= Modes.Length)
            {
                return(0);
            }

            // now calculate the totals...
            var prevMode = Modes[modeIndex];

            return(mode.BlockSize / 4 + prevMode.BlockSize / 4);
        }
Beispiel #10
0
        internal static VorbisFloor Create(VorbisStreamDecoder vorbis, DataPacket packet)
        {
            int type = (int)packet.ReadUBits(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);
        }
        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.ReadUBits(_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 (int 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 (int j = 0; j < _channels; j++)
                {
                    if (_mode.Mapping.ChannelSubmap[j] != subMap)
                    {
                        _floorData[j].ForceNoEnergy = true;
                    }
                }

                float[][] rTemp = subMap.Residue.Decode(packet, _noExecuteChannel, _channels, _mode.BlockSize);
                for (int c = 0; c < _channels; c++)
                {
                    var r  = _residue[c];
                    var rt = rTemp[c];
                    for (int 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);
        }
        void InitLookupTable(DataPacket packet)
        {
            MapType = (int)packet.ReadUBits(4);
            if (MapType == 0)
            {
                return;
            }

            float minValue   = Utils.ConvertFromVorbisFloat32(packet.ReadUInt32());
            float deltaValue = Utils.ConvertFromVorbisFloat32(packet.ReadUInt32());
            int   valueBits  = (int)packet.ReadUBits(4) + 1;
            bool  sequence_p = packet.ReadBit();

            int lookupValueCount = Entries * Dimensions;

            LookupTable = new float[lookupValueCount];
            if (MapType == 1)
            {
                lookupValueCount = Lookup1_values();
            }

            Span <uint> multiplicands = stackalloc uint[lookupValueCount];

            for (var i = 0; i < lookupValueCount; i++)
            {
                multiplicands[i] = (uint)packet.ReadUBits(valueBits);
            }

            // now that we have the initial data read in, calculate the entry tree
            if (MapType == 1)
            {
                for (int idx = 0; idx < Entries; idx++)
                {
                    double last   = 0.0;
                    int    idxDiv = 1;
                    for (var i = 0; i < Dimensions; i++)
                    {
                        int    moff  = idx / idxDiv % lookupValueCount;
                        double value = multiplicands[moff] * deltaValue + minValue + last;
                        LookupTable[idx * Dimensions + i] = (float)value;

                        if (sequence_p)
                        {
                            last = value;
                        }

                        idxDiv *= lookupValueCount;
                    }
                }
            }
            else
            {
                for (int idx = 0; idx < Entries; idx++)
                {
                    double last = 0.0;
                    int    moff = idx * Dimensions;
                    for (var i = 0; i < Dimensions; i++)
                    {
                        double value = multiplicands[moff] * deltaValue + minValue + last;
                        LookupTable[idx * Dimensions + i] = (float)value;

                        if (sequence_p)
                        {
                            last = value;
                        }

                        moff++;
                    }
                }
            }
        }
        bool LoadBooks(DataPacket packet)
        {
            if (!CheckForHeader(packet, bookHeader))
            {
                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 (int i = 0; i < Books.Length; i++)
            {
                Books[i] = VorbisCodebook.Create(this, packet, i);
            }

            _bookBits += packet.BitsRead - bits;
            bits       = packet.BitsRead;

            // get times
            Times = new VorbisTime[(int)packet.ReadUBits(6) + 1];
            for (int 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.ReadUBits(6) + 1];
            for (int i = 0; i < Floors.Length; i++)
            {
                Floors[i] = VorbisFloor.Create(this, packet);
            }

            _floorHdrBits += packet.BitsRead - bits;
            bits           = packet.BitsRead;

            // get residue
            Residues = new VorbisResidue[(int)packet.ReadUBits(6) + 1];
            for (int 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.ReadUBits(6) + 1];
            for (int i = 0; i < Maps.Length; i++)
            {
                Maps[i] = VorbisMapping.Create(this, packet);
            }

            _mapHdrBits += packet.BitsRead - bits;
            bits         = packet.BitsRead;

            // get mode settings
            Modes = new VorbisMode[(int)packet.ReadUBits(6) + 1];
            for (int 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);
        }
Beispiel #14
0
            protected override void Init(DataPacket packet)
            {
                // this is pretty well stolen directly from libvorbis...  BSD license
                _order         = (int)packet.ReadUBits(8);
                _rate          = (int)packet.ReadUBits(16);
                _bark_map_size = (int)packet.ReadUBits(16);
                _ampBits       = (int)packet.ReadUBits(6);
                _ampOfs        = (int)packet.ReadUBits(8);
                _books         = new VorbisCodebook[(int)packet.ReadUBits(4) + 1];

                if (_order < 1 || _rate < 1 || _bark_map_size < 1 || _books.Length == 0)
                {
                    throw new InvalidDataException();
                }

                _ampDiv = (1 << _ampBits) - 1;

                for (int i = 0; i < _books.Length; i++)
                {
                    int num = (int)packet.ReadUBits(8);
                    if (num < 0 || num >= _vorbis.Books.Length)
                    {
                        throw new InvalidDataException();
                    }
                    VorbisCodebook 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 (int i = 0; i < _reusablePacketData.Length; i++)
                {
                    _reusablePacketData[i] = new PacketData0()
                    {
                        Coeff = new float[_order + 1]
                    }
                }
                ;
            }

            int[] SynthesizeBarkCurve(int n)
            {
                float scale = _bark_map_size / ToBARK(_rate / 2);

                int[] map = new int[n + 1];

                for (int i = 0; i < n - 1; i++)
                {
                    map[i] = Math.Min(_bark_map_size - 1, (int)MathF.Floor(ToBARK(_rate / 2f / n * i) * scale));
                }

                map[n] = -1;
                return(map);
            }
        void InitTree(DataPacket packet)
        {
            bool sparse;
            int  total = 0;

            if (packet.ReadBit())
            {
                // ordered
                var len = (int)packet.ReadUBits(5) + 1;
                for (var i = 0; i < Entries;)
                {
                    int cnt = (int)packet.ReadUBits(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.ReadUBits(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)
            {
                Span <int> codewordLengths = stackalloc int[0];
                if (sparse && total >= Entries >> 2)
                {
                    codewordLengths = stackalloc int[Entries];
                    for (int i = 0; i < Entries; i++)
                    {
                        codewordLengths[i] = Lengths[i];
                    }

                    sparse = false;
                }

                // compute size of sorted tables
                int sortedEntries = sparse ? total : 0;

                Span <int> values    = stackalloc int[0];
                Span <int> codewords = stackalloc int[0];
                if (!sparse)
                {
                    codewords = stackalloc int[Entries];
                }
                else if (sortedEntries != 0)
                {
                    codewordLengths = stackalloc int[sortedEntries];
                    codewords       = stackalloc int[sortedEntries];
                    values          = stackalloc int[sortedEntries];
                }

                if (!ComputeCodewords(sparse, sortedEntries, codewords, codewordLengths, Lengths, Entries, values))
                {
                    throw new InvalidDataException();
                }

                Span <int> valueList = stackalloc int[codewords.Length];
                if (values.Length != 0)
                {
                    valueList = values;
                }
                else
                {
                    for (int i = 0; i < codewords.Length; i++)
                    {
                        valueList[i] = i;
                    }
                }

                Span <int> lengthList = codewordLengths.Length > 0 ? codewordLengths : Lengths.AsSpan();
                PrefixList = Huffman.BuildPrefixedLinkedList(
                    valueList, lengthList, codewords, out PrefixBitLength, out PrefixOverflowTree);
            }
        }
Beispiel #16
0
            protected override void Init(DataPacket packet)
            {
                _partitionClass = new int[(int)packet.ReadUBits(5)];
                for (int i = 0; i < _partitionClass.Length; i++)
                {
                    _partitionClass[i] = (int)packet.ReadUBits(4);
                }

                int 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 (int i = 0; i <= maximum_class; i++)
                {
                    _classDimensions[i] = (int)packet.ReadUBits(3) + 1;
                    _classSubclasses[i] = (int)packet.ReadUBits(2);
                    if (_classSubclasses[i] > 0)
                    {
                        _classMasterBookIndex[i] = (int)packet.ReadUBits(8);
                        _classMasterBooks[i]     = _vorbis.Books[_classMasterBookIndex[i]];
                    }

                    _subclassBooks[i]     = new VorbisCodebook[1 << _classSubclasses[i]];
                    _subclassBookIndex[i] = new int[_subclassBooks[i].Length];
                    for (int j = 0; j < _subclassBooks[i].Length; j++)
                    {
                        int bookNum = (int)packet.ReadUBits(8) - 1;
                        if (bookNum >= 0)
                        {
                            _subclassBooks[i][j] = _vorbis.Books[bookNum];
                        }
                        _subclassBookIndex[i][j] = bookNum;
                    }
                }

                _multiplier = (int)packet.ReadUBits(2);
                _range      = _rangeLookup[_multiplier];
                _yBits      = _yBitsLookup[_multiplier];
                _multiplier++;

                int rangeBits = (int)packet.ReadUBits(4);

                int xListIndex = 0;
                int xListSize  = 2;                              // we always add at least 2 elements

                for (int i = 0; i < _partitionClass.Length; i++) // precalc size of xList
                {
                    int classNum = _partitionClass[i];
                    int dim      = _classDimensions[classNum];
                    xListSize += dim;
                }
                _xList = new int[xListSize];
                _xList[xListIndex++] = 0;
                _xList[xListIndex++] = 1 << rangeBits;

                for (int i = 0; i < _partitionClass.Length; i++)
                {
                    int classNum = _partitionClass[i];
                    int dim      = _classDimensions[classNum];
                    for (int j = 0; j < dim; j++)
                    {
                        _xList[xListIndex++] = (int)packet.ReadUBits(rangeBits);
                    }
                }

                // precalc the low and high neighbors (and init the sort table)
                _lNeigh     = new int[_xList.Length];
                _hNeigh     = new int[_xList.Length];
                _sortIdx    = new int[_xList.Length];
                _sortIdx[0] = 0;
                _sortIdx[1] = 1;

                for (int i = 2; i < _lNeigh.Length; i++)
                {
                    _lNeigh[i]  = 0;
                    _hNeigh[i]  = 1;
                    _sortIdx[i] = i;
                    for (int j = 2; j < i; j++)
                    {
                        int tmp = _xList[j];
                        if (tmp < _xList[i])
                        {
                            if (tmp > _xList[_lNeigh[i]])
                            {
                                _lNeigh[i] = j;
                            }
                        }
                        else
                        {
                            if (tmp < _xList[_hNeigh[i]])
                            {
                                _hNeigh[i] = j;
                            }
                        }
                    }
                }

                // precalc the sort table
                for (int i = 0; i < _sortIdx.Length - 1; i++)
                {
                    for (int 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
                            int tmp = _sortIdx[i];
                            _sortIdx[i] = _sortIdx[j];
                            _sortIdx[j] = tmp;
                        }
                    }
                }

                // pre-create our packet data instances
                _reusablePacketData = new PacketData1[_vorbis._channels];
                for (int i = 0; i < _reusablePacketData.Length; i++)
                {
                    _reusablePacketData[i] = new PacketData1();
                }
            }
Beispiel #17
0
            protected override void Init(DataPacket packet)
            {
                // this is pretty well stolen directly from libvorbis...  BSD license
                _begin           = (int)packet.ReadUBits(24);
                _end             = (int)packet.ReadUBits(24);
                _partitionSize   = (int)packet.ReadUBits(24) + 1;
                _classifications = (int)packet.ReadUBits(6) + 1;
                _classBook       = _vorbis.Books[(int)packet.ReadUBits(8)];

                _cascade = new int[_classifications];
                int acc = 0;

                for (int i = 0; i < _classifications; i++)
                {
                    var low_bits = (int)packet.ReadUBits(3);
                    if (packet.ReadBit())
                    {
                        _cascade[i] = (int)packet.ReadUBits(5) << 3 | low_bits;
                    }
                    else
                    {
                        _cascade[i] = low_bits;
                    }

                    acc += ICount(_cascade[i]);
                }

                int[] bookNums = new int[acc];
                for (var i = 0; i < acc; i++)
                {
                    bookNums[i] = (int)packet.ReadUBits(8);
                    if (_vorbis.Books[bookNums[i]].MapType == 0)
                    {
                        throw new InvalidDataException();
                    }
                }

                int entries  = _classBook.Entries;
                int dim      = _classBook.Dimensions;
                int partvals = 1;

                while (dim > 0)
                {
                    partvals *= _classifications;
                    if (partvals > entries)
                    {
                        throw new InvalidDataException();
                    }
                    --dim;
                }

                // now the lookups
                _ = _classBook.Dimensions;

                _books = new VorbisCodebook[_classifications][];

                acc = 0;
                var maxstage = 0;
                int stages;

                for (int j = 0; j < _classifications; j++)
                {
                    stages    = Utils.ILog(_cascade[j]);
                    _books[j] = new VorbisCodebook[stages];
                    if (stages > 0)
                    {
                        maxstage = Math.Max(maxstage, stages);
                        for (int 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 (int j = 0; j < partvals; j++)
                {
                    var val  = j;
                    var mult = partvals / _classifications;
                    _decodeMap[j] = new int[_classBook.Dimensions];
                    for (int 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 (int ch = 0; ch < _vorbis._channels; ch++)
                {
                    _partWordCache[ch] = new int[maxPartWords][];
                }
            }
Beispiel #18
0
            protected override void Init(DataPacket packet)
            {
                var submapCount = 1;

                if (packet.ReadBit())
                {
                    submapCount += (int)packet.ReadUBits(4);
                }

                // square polar mapping
                var couplingSteps = 0;

                if (packet.ReadBit())
                {
                    couplingSteps = (int)packet.ReadUBits(8) + 1;
                }

                var couplingBits = Utils.ILog(_vorbis._channels - 1);

                CouplingSteps = new CouplingStep[couplingSteps];
                for (int j = 0; j < couplingSteps; j++)
                {
                    var magnitude = (int)packet.ReadUBits(couplingBits);
                    var angle     = (int)packet.ReadUBits(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.ReadUBits(2) != 0UL)
                {
                    throw new InvalidDataException();
                }

                // channel multiplex
                var mux = new int[_vorbis._channels];

                if (submapCount > 1)
                {
                    for (int c = 0; c < ChannelSubmap.Length; c++)
                    {
                        mux[c] = (int)packet.ReadUBits(4);
                        if (mux[c] >= submapCount)
                        {
                            throw new InvalidDataException();
                        }
                    }
                }

                // submaps
                Submaps = new Submap[submapCount];
                for (int j = 0; j < submapCount; j++)
                {
                    packet.ReadUBits(8); // unused placeholder
                    var floorNum = (int)packet.ReadUBits(8);
                    if (floorNum >= _vorbis.Floors.Length)
                    {
                        throw new InvalidDataException();
                    }
                    var residueNum = (int)packet.ReadUBits(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 (int c = 0; c < ChannelSubmap.Length; c++)
                {
                    ChannelSubmap[c] = Submaps[mux[c]];
                }
            }