////------------------------------------------------------------------------------------------------------------------------------ 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; }