Beispiel #1
0
        virtual public void Decode(IPacket packet, bool[] doNotDecodeChannel, int blockSize, float[][] buffer)
        {
            // this is pretty well stolen directly from libvorbis...  BSD license
            var end = _end < blockSize / 2 ? _end : blockSize / 2;
            var n   = end - _begin;

            if (n > 0 && Array.IndexOf(doNotDecodeChannel, false) != -1)
            {
                var partitionCount = n / _partitionSize;

                var partitionWords = (partitionCount + _classBook.Dimensions - 1) / _classBook.Dimensions;
                var partWordCache  = new int[_channels, partitionWords][];

                for (var stage = 0; stage < _maxStages; stage++)
                {
                    for (int partitionIdx = 0, entryIdx = 0; partitionIdx < partitionCount; entryIdx++)
                    {
                        if (stage == 0)
                        {
                            for (var ch = 0; ch < _channels; ch++)
                            {
                                var idx = _classBook.DecodeScalar(packet);
                                if (idx >= 0 && idx < _decodeMap.Length)
                                {
                                    partWordCache[ch, entryIdx] = _decodeMap[idx];
                                }
                                else
                                {
                                    partitionIdx = partitionCount;
                                    stage        = _maxStages;
                                    break;
                                }
                            }
                        }
                        for (var dimensionIdx = 0; partitionIdx < partitionCount && dimensionIdx < _classBook.Dimensions; dimensionIdx++, partitionIdx++)
                        {
                            var offset = _begin + partitionIdx * _partitionSize;
                            for (var ch = 0; ch < _channels; ch++)
                            {
                                var idx = partWordCache[ch, entryIdx][dimensionIdx];
                                if ((_cascade[idx] & (1 << stage)) != 0)
                                {
                                    var book = _books[idx][stage];
                                    if (book != null)
                                    {
                                        if (WriteVectors(book, packet, buffer, ch, offset, _partitionSize))
                                        {
                                            // bad packet...  exit now and try to use what we already have
                                            partitionIdx = partitionCount;
                                            stage        = _maxStages;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #2
0
        protected override bool WriteVectors(ICodebook codebook, IPacket packet, float[][] residue, int channel, int offset, int partitionSize)
        {
            var chPtr = 0;

            offset /= _channels;
            for (int c = 0; c < partitionSize;)
            {
                var entry = codebook.DecodeScalar(packet);
                if (entry == -1)
                {
                    return(true);
                }
                for (var d = 0; d < codebook.Dimensions; d++, c++)
                {
                    residue[chPtr][offset] += codebook[entry, d];
                    if (++chPtr == _channels)
                    {
                        chPtr = 0;
                        offset++;
                    }
                }
            }

            return(false);
        }
Beispiel #3
0
        protected override bool WriteVectors(ICodebook codebook, IPacket packet, float[][] residue, int channel, int offset, int partitionSize)
        {
            var res = residue[channel];

            for (int i = 0; i < partitionSize;)
            {
                var entry = codebook.DecodeScalar(packet);
                if (entry == -1)
                {
                    return(true);
                }
                for (int j = 0; j < codebook.Dimensions; i++, j++)
                {
                    res[offset + i] += codebook[entry, j];
                }
            }

            return(false);
        }
Beispiel #4
0
        virtual protected bool WriteVectors(ICodebook codebook, IPacket packet, float[][] residue, int channel, int offset, int partitionSize)
        {
            var res        = residue[channel];
            var steps      = partitionSize / codebook.Dimensions;
            var entryCache = new int[steps];

            for (var i = 0; i < steps; i++)
            {
                if ((entryCache[i] = codebook.DecodeScalar(packet)) == -1)
                {
                    return(true);
                }
            }
            for (var dim = 0; dim < codebook.Dimensions; dim++)
            {
                for (var step = 0; step < steps; step++, offset++)
                {
                    res[offset] += codebook[entryCache[step], dim];
                }
            }
            return(false);
        }
Beispiel #5
0
        public virtual void Decode(
            IPacket packet, ReadOnlySpan <bool> doNotDecodeChannel, int blockSize, float[][] buffer)
        {
            // this is pretty well stolen directly from libvorbis...  BSD license
            int end = _end < blockSize / 2 ? _end : blockSize / 2;
            int n   = end - _begin;

            if (n <= 0 || doNotDecodeChannel.IndexOf(false) == -1)
            {
                return;
            }

            int partitionCount = n / _partitionSize;
            int partitionWords = (partitionCount + _classBook.Dimensions - 1) / _classBook.Dimensions;

            int partitionWordCacheSize = partitionWords * _channels;
            var partWordCache          = partitionWordCacheSize <= 1024
                ? stackalloc int[partitionWordCacheSize]
                : new int[partitionWordCacheSize];

            for (int stage = 0; stage < _maxStages; stage++)
            {
                for (int partitionIdx = 0, entryIdx = 0; partitionIdx < partitionCount; entryIdx++)
                {
                    if (stage == 0)
                    {
                        for (int ch = 0; ch < _channels; ch++)
                        {
                            int idx = _classBook.DecodeScalar(packet);
                            if (idx >= 0 && idx < _decodeMap.Length)
                            {
                                partWordCache[entryIdx * _channels + ch] = idx;
                            }
                            else
                            {
                                partitionIdx = partitionCount;
                                stage        = _maxStages;
                                break;
                            }
                        }
                    }

                    for (
                        int dimensionIdx = 0;
                        partitionIdx < partitionCount && dimensionIdx < _classBook.Dimensions;
                        dimensionIdx++, partitionIdx++)
                    {
                        int offset = _begin + partitionIdx * _partitionSize;
                        for (int ch = 0; ch < _channels; ch++)
                        {
                            int mapIndex = partWordCache[entryIdx * _channels + ch];
                            int index    = _decodeMap[mapIndex][dimensionIdx];

                            if ((_cascade[index] & (1 << stage)) != 0)
                            {
                                var book = _books[index][stage];
                                if (book != null)
                                {
                                    if (WriteVectors(book, packet, buffer, ch, offset, _partitionSize))
                                    {
                                        // bad packet...  exit now and try to use what we already have
                                        partitionIdx = partitionCount;
                                        stage        = _maxStages;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }