public ChannelLPC(BitInputStream is, Header header, ChannelData channelData, int bps, int wastedBits, int order) throws IOException {
        super(header, wastedBits);

        this.residual = channelData.getResidual();
        this.order = order;

        // read warm-up samples
        //System.out.println("Order="+order);
        for (int u = 0; u < order; u++) {
            warmup[u] = is.readRawInt(bps);
        }
        //for (int i = 0; i < order; i++) System.out.println("Warm "+i+" "+warmup[i]);

        // read qlp coeff precision
        int u32 = is.readRawUInt(SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN);
        if (u32 == (1 << SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1) {
            throw new IOException("STREAM_DECODER_ERROR_STATUS_LOST_SYNC");
        }
        qlpCoeffPrecision = u32 + 1;
        //System.out.println("qlpCoeffPrecision="+qlpCoeffPrecision);

        // read qlp shift
        quantizationLevel = is.readRawInt(SUBFRAME_LPC_QLP_SHIFT_LEN);
        //System.out.println("quantizationLevel="+quantizationLevel);

        // read quantized lp coefficiencts
        for (int u = 0; u < order; u++) {
            qlpCoeff[u] = is.readRawInt(qlpCoeffPrecision);
        }

        // read entropy coding method info
        int codingType = is.readRawUInt(ENTROPY_CODING_METHOD_TYPE_LEN);
        //System.out.println("codingType="+codingType);
        switch (codingType) {
            case ENTROPY_CODING_METHOD_PARTITIONED_RICE :
                entropyCodingMethod = new EntropyPartitionedRice();
                ((EntropyPartitionedRice) entropyCodingMethod).order = is.readRawUInt(ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN);
                ((EntropyPartitionedRice) entropyCodingMethod).contents = channelData.getPartitionedRiceContents();
                break;
            default :
                throw new IOException("STREAM_DECODER_UNPARSEABLE_STREAM");
        }
 
        // read residual
        if (entropyCodingMethod instanceof EntropyPartitionedRice) {
            ((EntropyPartitionedRice) entropyCodingMethod).readResidual(is, 
                order,
                ((EntropyPartitionedRice) entropyCodingMethod).order,
                header,
                channelData.getResidual());
        }
        
        //System.out.println();
        //for (int i = 0; i < header.blockSize; i++) {System.out.print(channelData.residual[i]+" ");
        //if (i%200==0)System.out.println();
        //}
        //System.out.println();

        // decode the subframe
        System.arraycopy(warmup, 0, channelData.getOutput(), 0, order);
        if (bps + qlpCoeffPrecision + BitMath.ilog2(order) <= 32) {
            if (bps <= 16 && qlpCoeffPrecision <= 16)
                LPCPredictor.restoreSignal(channelData.getResidual(), header.blockSize - order, qlpCoeff, order, quantizationLevel, channelData.getOutput(), order);
            else
                LPCPredictor.restoreSignal(channelData.getResidual(), header.blockSize - order, qlpCoeff, order, quantizationLevel, channelData.getOutput(), order);
        } else {
            LPCPredictor.restoreSignalWide(channelData.getResidual(), header.blockSize - order, qlpCoeff, order, quantizationLevel, channelData.getOutput(), order);
        }
    }