static void filter_channel(MLPDecodeContext *m, unsigned int substr,

                           unsigned int channel)

{

    SubStream *s = &m->substream[substr];

    int32_t firbuf[MAX_BLOCKSIZE + MAX_FIR_ORDER];

    int32_t iirbuf[MAX_BLOCKSIZE + MAX_IIR_ORDER];

    FilterParams *fir = &m->channel_params[channel].filter_params[FIR];

    FilterParams *iir = &m->channel_params[channel].filter_params[IIR];

    unsigned int filter_shift = fir->shift;

    int32_t mask = MSB_MASK(s->quant_step_size[channel]);

    int index = MAX_BLOCKSIZE;

    int i;



    memcpy(&firbuf[MAX_BLOCKSIZE], &fir->state[0],

            MAX_FIR_ORDER * sizeof(int32_t));

    memcpy(&iirbuf[MAX_BLOCKSIZE], &iir->state[0],

            MAX_IIR_ORDER * sizeof(int32_t));



    for (i = 0; i < s->blocksize; i++) {

        int32_t residual = m->sample_buffer[i + s->blockpos][channel];

        unsigned int order;

        int64_t accum = 0;

        int32_t result;



        



        for (order = 0; order < fir->order; order++)

            accum += (int64_t)firbuf[index + order] *

                                fir->coeff[order];

        for (order = 0; order < iir->order; order++)

            accum += (int64_t)iirbuf[index + order] *

                                iir->coeff[order];



        accum  = accum >> filter_shift;

        result = (accum + residual) & mask;



        --index;



        firbuf[index] = result;

        iirbuf[index] = result - accum;



        m->sample_buffer[i + s->blockpos][channel] = result;

    }



    memcpy(&fir->state[0], &firbuf[index],

            MAX_FIR_ORDER * sizeof(int32_t));

    memcpy(&iir->state[0], &iirbuf[index],

            MAX_IIR_ORDER * sizeof(int32_t));

}
