////------------------------------------------------------------------------------------------------------------------------------
        public static FlacRicePartition Read(StreamBuffer sb, int partitionNumber, int partitionOrder, int predictOrder, int blockSize, FlacResidualCodingMethod codingMethod)
        {
            FlacRicePartition ricePartition = new FlacRicePartition { _riceParameter = sb.ReadBigEndianInt32(), _codingMethod = codingMethod };
            int riceParameter = ricePartition._riceParameter & ((codingMethod == FlacResidualCodingMethod.PartitionedRice) ? 0x1F : 0xF);
            if (partitionOrder == 0)
                ricePartition.Samples = blockSize - predictOrder;
            else if (partitionNumber == 0)
                ricePartition.Samples = (blockSize >> partitionOrder) - predictOrder;
            else
                ricePartition.Samples = blockSize >> partitionOrder;

            ricePartition.Residuals = new int[ricePartition.Samples];
            if ((riceParameter < 0xF) || ((codingMethod == FlacResidualCodingMethod.PartitionedRice2) && (riceParameter < 0x1F)))
            {
                for (int i = 0; i < ricePartition.Samples; i++)
                {
                    long msbs = sb.ReadUnaryInt();
                    long lsbs = sb.ReadBigEndianInt32() & (0xFFFFFFFF >> (32 - riceParameter));
                    long value = (msbs << riceParameter) | lsbs;
                    ricePartition.Residuals[i] = ((value & 0x01) == 0x01) ? -((int)(value >> 1)) - 1 : (int)(value >> 1);
                }
            }
            else
            {
                // residuals in unencoded form, sample size read from the next 5
                // bits in the stream.
                int size = sb.ReadBigEndianInt32();
                for (int i = 0; i < ricePartition.Samples; i++)
                    ricePartition.Residuals[i] = sb.ReadBigEndianInt32();
            }
            return ricePartition;
        }
Esempio n. 2
0
        public static unsafe void ProcessResidual(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data,
            int order, int partitionOrder, FlacResidualCodingMethod codingMethod)
        {
            data.Content.UpdateSize(partitionOrder);
            bool isRice2 = codingMethod == FlacResidualCodingMethod.PartitionedRice2;
            int riceParameterLength = isRice2 ? 5 : 4;
            int escapeCode = isRice2 ? 31 : 15; //11111 : 1111

            int samplesPerPartition;

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

            int* residualBuffer = data.ResidualBuffer + order;

            for (int p = 0; p < partitionCount; p++)
            {
                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 (int i = 0; i < samplesPerPartition; i++)
                    {
                        int sample = reader.ReadBitsSigned((int)raw);
                        *(residualBuffer) = sample;
                        residualBuffer++;
                    }
                }
                else
                {
                    ReadFlacRiceBlock(reader, samplesPerPartition, (int)riceParameter, residualBuffer);
                    residualBuffer += samplesPerPartition;
                }
            }
        }
Esempio n. 3
0
        public FlacResidual(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int order)
        {
            FlacResidualCodingMethod codingMethod = (FlacResidualCodingMethod)reader.ReadBits(2); // 2 Bit

            if (codingMethod == FlacResidualCodingMethod.PartitionedRice || codingMethod == FlacResidualCodingMethod.PartitionedRice2)
            {
                int partitionOrder = (int)reader.ReadBits(4); //"Partition order." see https://xiph.org/flac/format.html#partitioned_rice and https://xiph.org/flac/format.html#partitioned_rice2

                FlacPartitionedRice.ProcessResidual(reader, header, data, order, partitionOrder, codingMethod);

#if FLAC_DEBUG
                CodingMethodMethod = codingMethod;
                PartitionOrder     = partitionOrder;
#endif
            }
            else
            {
                throw new FlacException("Not supported RICE-Coding-Method. Stream unparseable!", FlacLayer.SubFrame);
            }
        }