Ejemplo n.º 1
0
        private unsafe List<FlacSubFrameData> AllocOuputMemory()
        {
            if (_destBuffer == null || _destBuffer.Length < (Header.Channels * Header.BlockSize))
                _destBuffer = new int[Header.Channels * Header.BlockSize];
            if (_residualBuffer == null || _residualBuffer.Length < (Header.Channels * Header.BlockSize))
                _residualBuffer = new int[Header.Channels * Header.BlockSize];

            var output = new List<FlacSubFrameData>();

            for (var c = 0; c < Header.Channels; c++)
            {
                fixed (int* ptrDestBuffer = _destBuffer, ptrResidualBuffer = _residualBuffer)
                {
                    _handle1 = GCHandle.Alloc(_destBuffer, GCHandleType.Pinned);
                    _handle2 = GCHandle.Alloc(_residualBuffer, GCHandleType.Pinned);

                    var data = new FlacSubFrameData
                    {
                        DestinationBuffer = _destBuffer.AsMemory(c * Header.BlockSize),
                        ResidualBuffer = _residualBuffer.AsMemory(c * Header.BlockSize)
                    };
                    output.Add(data);
                }
            }

            return output;
        }
Ejemplo n.º 2
0
        public static void ProcessResidual(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data,
                                           int order, int partitionOrder, FlacResidualCodingMethod codingMethod)
        {
            data.Content.UpdateSize(partitionOrder);
            var isRice2             = codingMethod == FlacResidualCodingMethod.PartitionedRice2;
            var riceParameterLength = isRice2 ? 5 : 4;
            var escapeCode          = isRice2 ? 31 : 15; //11111 : 1111

            var partitionCount = 1 << partitionOrder;    //2^partitionOrder -> There will be 2^order partitions. -> "order" = partitionOrder in this case

            var residualBuffer = data.ResidualBuffer.Span.Slice(order);

            for (var p = 0; p < partitionCount; p++)
            {
                int samplesPerPartition;
                if (partitionOrder == 0)
                {
                    samplesPerPartition = header.BlockSize - order;
                }
                else if (p > 0)
                {
                    samplesPerPartition = header.BlockSize >> partitionOrder;
                }
                else
                {
                    samplesPerPartition = (header.BlockSize >> partitionOrder) - order;
                }

                var riceParameter = reader.ReadBits(riceParameterLength);
                data.Content.Parameters[p] = (int)riceParameter;

                if (riceParameter >= escapeCode)
                {
                    var raw = reader.ReadBits(5); //raw is always 5 bits (see ...(+5))
                    data.Content.RawBits[p] = (int)raw;
                    for (var i = 0; i < samplesPerPartition; i++)
                    {
                        var sample = reader.ReadBitsSigned((int)raw);
                        residualBuffer[i] = sample;
                    }
                }
                else
                {
                    ReadFlacRiceBlock(reader, samplesPerPartition, (int)riceParameter, residualBuffer);
                }

                residualBuffer = residualBuffer.Slice(samplesPerPartition);
            }
        }