int[] ReadResidual( FlacBitReader bitReader, int predictorOrder, int blockSize ) { int encodingMethod = bitReader.ReadBits( 2 ); if( !( encodingMethod == 0 || encodingMethod == 1 ) ) { throw new InvalidDataException( "Invalid rice encoding method." ); } bool extended = encodingMethod == 1; int partitionOrder = bitReader.ReadBits( 4 ); int partitionsCount = 1 << partitionOrder; // 2^x. int partitionSamples = partitionOrder > 0 ? blockSize >> partitionOrder : blockSize - predictorOrder; int paramLength = extended ? rice2ParamLength : riceParamLength; int escapeParam = extended ? rice2EscapeParam : riceEscapeParam; int sample = 0; int[] residual = new int[blockSize - predictorOrder]; for( int partition = 0; partition < partitionsCount; partition++ ) { int riceParam = bitReader.ReadBits( paramLength ); if( riceParam < escapeParam ) { int n = ( partitionOrder == 0 || partition > 0 ) ? partitionSamples : partitionSamples - predictorOrder; for( int i = 0; i < n; i++ ) { residual[sample + i] = bitReader.ReadRice( riceParam ); } sample += n; } else { int rawParamLength = bitReader.ReadBits( riceEscapeParamLength ); int n = ( partitionOrder == 0 || partition > 0 ) ? partitionSamples : partitionSamples - predictorOrder; for( int i = 0; i < n; i++ ) { residual[sample + i] = bitReader.ReadBits( rawParamLength ); } sample += n; } } return residual; }