static void lms_update(WmallDecodeCtx *s, int ich, int ilms, int16_t input, int16_t pred)

{

    int16_t icoef;

    int recent = s->cdlms[ich][ilms].recent;

    int16_t range = 1 << (s->bits_per_sample - 1);

    int bps = s->bits_per_sample > 16 ? 4 : 2; // bytes per sample



    if (input > pred) {

        for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)

            s->cdlms[ich][ilms].coefs[icoef] +=

                s->cdlms[ich][ilms].lms_updates[icoef + recent];

    } else {

        for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)

            s->cdlms[ich][ilms].coefs[icoef] -=

                s->cdlms[ich][ilms].lms_updates[icoef];     // XXX: [icoef + recent] ?

    }

    s->cdlms[ich][ilms].recent--;

    s->cdlms[ich][ilms].lms_prevvalues[recent] = av_clip(input, -range, range - 1);



    if (input > pred)

        s->cdlms[ich][ilms].lms_updates[recent] = s->update_speed[ich];

    else if (input < pred)

        s->cdlms[ich][ilms].lms_updates[recent] = -s->update_speed[ich];



    /* XXX: spec says:

    cdlms[iCh][ilms].updates[iRecent + cdlms[iCh][ilms].order >> 4] >>= 2;

    lms_updates[iCh][ilms][iRecent + cdlms[iCh][ilms].order >> 3] >>= 1;



        Questions is - are cdlms[iCh][ilms].updates[] and lms_updates[][][] two

        seperate buffers? Here I've assumed that the two are same which makes

        more sense to me.

    */

    s->cdlms[ich][ilms].lms_updates[recent + s->cdlms[ich][ilms].order >> 4] >>= 2;

    s->cdlms[ich][ilms].lms_updates[recent + s->cdlms[ich][ilms].order >> 3] >>= 1;

    /* XXX: recent + (s->cdlms[ich][ilms].order >> 4) ? */



    if (s->cdlms[ich][ilms].recent == 0) {

        /* XXX: This memcpy()s will probably fail if a fixed 32-bit buffer is used.

                follow kshishkov's suggestion of using a union. */

        memcpy(s->cdlms[ich][ilms].lms_prevvalues + s->cdlms[ich][ilms].order,

               s->cdlms[ich][ilms].lms_prevvalues,

               bps * s->cdlms[ich][ilms].order);

        memcpy(s->cdlms[ich][ilms].lms_updates + s->cdlms[ich][ilms].order,

               s->cdlms[ich][ilms].lms_updates,

               bps * s->cdlms[ich][ilms].order);

        s->cdlms[ich][ilms].recent = s->cdlms[ich][ilms].order;

    }

}

static void lms_update(WmallDecodeCtx *s, int ich, int ilms, int16_t input, int16_t pred)

{

    int16_t icoef;

    int recent = s->cdlms[ich][ilms].recent;

    int16_t range = 1 << (s->bits_per_sample - 1);

    int bps = s->bits_per_sample > 16 ? 4 : 2; 



    if (input > pred) {

        for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)

            s->cdlms[ich][ilms].coefs[icoef] +=

                s->cdlms[ich][ilms].lms_updates[icoef + recent];

    } else {

        for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)

            s->cdlms[ich][ilms].coefs[icoef] -=

                s->cdlms[ich][ilms].lms_updates[icoef];     

    }

    s->cdlms[ich][ilms].recent--;

    s->cdlms[ich][ilms].lms_prevvalues[recent] = av_clip(input, -range, range - 1);



    if (input > pred)

        s->cdlms[ich][ilms].lms_updates[recent] = s->update_speed[ich];

    else if (input < pred)

        s->cdlms[ich][ilms].lms_updates[recent] = -s->update_speed[ich];



    















    s->cdlms[ich][ilms].lms_updates[recent + s->cdlms[ich][ilms].order >> 4] >>= 2;

    s->cdlms[ich][ilms].lms_updates[recent + s->cdlms[ich][ilms].order >> 3] >>= 1;

    



    if (s->cdlms[ich][ilms].recent == 0) {

        



        memcpy(s->cdlms[ich][ilms].lms_prevvalues + s->cdlms[ich][ilms].order,

               s->cdlms[ich][ilms].lms_prevvalues,

               bps * s->cdlms[ich][ilms].order);

        memcpy(s->cdlms[ich][ilms].lms_updates + s->cdlms[ich][ilms].order,

               s->cdlms[ich][ilms].lms_updates,

               bps * s->cdlms[ich][ilms].order);

        s->cdlms[ich][ilms].recent = s->cdlms[ich][ilms].order;

    }

}

    int16_t range = 1 << (s->bits_per_sample - 1);
static void FUNC_0(WmallDecodeCtx *VAR_0, int VAR_1, int VAR_2, int16_t VAR_3, int16_t VAR_4)

{

    int16_t icoef;

    int VAR_5 = VAR_0->cdlms[VAR_1][VAR_2].VAR_5;

    int16_t range = 1 << (VAR_0->bits_per_sample - 1);

    int VAR_6 = VAR_0->bits_per_sample > 16 ? 4 : 2; 



    if (VAR_3 > VAR_4) {

        for (icoef = 0; icoef < VAR_0->cdlms[VAR_1][VAR_2].order; icoef++)

            VAR_0->cdlms[VAR_1][VAR_2].coefs[icoef] +=

                VAR_0->cdlms[VAR_1][VAR_2].lms_updates[icoef + VAR_5];

    } else {

        for (icoef = 0; icoef < VAR_0->cdlms[VAR_1][VAR_2].order; icoef++)

            VAR_0->cdlms[VAR_1][VAR_2].coefs[icoef] -=

                VAR_0->cdlms[VAR_1][VAR_2].lms_updates[icoef];     

    }

    VAR_0->cdlms[VAR_1][VAR_2].VAR_5--;

    VAR_0->cdlms[VAR_1][VAR_2].lms_prevvalues[VAR_5] = av_clip(VAR_3, -range, range - 1);



    if (VAR_3 > VAR_4)

        VAR_0->cdlms[VAR_1][VAR_2].lms_updates[VAR_5] = VAR_0->update_speed[VAR_1];

    else if (VAR_3 < VAR_4)

        VAR_0->cdlms[VAR_1][VAR_2].lms_updates[VAR_5] = -VAR_0->update_speed[VAR_1];



    















    VAR_0->cdlms[VAR_1][VAR_2].lms_updates[VAR_5 + VAR_0->cdlms[VAR_1][VAR_2].order >> 4] >>= 2;

    VAR_0->cdlms[VAR_1][VAR_2].lms_updates[VAR_5 + VAR_0->cdlms[VAR_1][VAR_2].order >> 3] >>= 1;

    



    if (VAR_0->cdlms[VAR_1][VAR_2].VAR_5 == 0) {

        



        memcpy(VAR_0->cdlms[VAR_1][VAR_2].lms_prevvalues + VAR_0->cdlms[VAR_1][VAR_2].order,

               VAR_0->cdlms[VAR_1][VAR_2].lms_prevvalues,

               VAR_6 * VAR_0->cdlms[VAR_1][VAR_2].order);

        memcpy(VAR_0->cdlms[VAR_1][VAR_2].lms_updates + VAR_0->cdlms[VAR_1][VAR_2].order,

               VAR_0->cdlms[VAR_1][VAR_2].lms_updates,

               VAR_6 * VAR_0->cdlms[VAR_1][VAR_2].order);

        VAR_0->cdlms[VAR_1][VAR_2].VAR_5 = VAR_0->cdlms[VAR_1][VAR_2].order;

    }

}

static void FUNC_0(WmallDecodeCtx *VAR_0, int VAR_1, int VAR_2, int16_t VAR_3, int16_t VAR_4)
{ int16_t icoef; int VAR_5 = VAR_0->cdlms[VAR_1][VAR_2].VAR_5; int16_t range = 1 << (VAR_0->bits_per_sample - 1); int VAR_6 = VAR_0->bits_per_sample > 16 ? 4 : 2; if (VAR_3 > VAR_4) { for (icoef = 0; icoef < VAR_0->cdlms[VAR_1][VAR_2].order; icoef++) VAR_0->cdlms[VAR_1][VAR_2].coefs[icoef] +=
VAR_0->cdlms[VAR_1][VAR_2].lms_updates[icoef + VAR_5]; } else { for (icoef = 0; icoef < VAR_0->cdlms[VAR_1][VAR_2].order; icoef++) VAR_0->cdlms[VAR_1][VAR_2].coefs[icoef] -=
VAR_0->cdlms[VAR_1][VAR_2].lms_updates[icoef]; } VAR_0->cdlms[VAR_1][VAR_2].VAR_5--; VAR_0->cdlms[VAR_1][VAR_2].lms_prevvalues[VAR_5] = av_clip(VAR_3, -range, range - 1); if (VAR_3 > VAR_4)
VAR_0->cdlms[VAR_1][VAR_2].lms_updates[VAR_5] = VAR_0->update_speed[VAR_1]; else if (VAR_3 < VAR_4)
VAR_0->cdlms[VAR_1][VAR_2].lms_updates[VAR_5] = -VAR_0->update_speed[VAR_1]; VAR_0->cdlms[VAR_1][VAR_2].lms_updates[VAR_5 + VAR_0->cdlms[VAR_1][VAR_2].order >> 4] >>= 2; VAR_0->cdlms[VAR_1][VAR_2].lms_updates[VAR_5 + VAR_0->cdlms[VAR_1][VAR_2].order >> 3] >>= 1; if (VAR_0->cdlms[VAR_1][VAR_2].VAR_5 == 0) { memcpy(VAR_0->cdlms[VAR_1][VAR_2].lms_prevvalues + VAR_0->cdlms[VAR_1][VAR_2].order,
VAR_0->cdlms[VAR_1][VAR_2].lms_prevvalues,
VAR_6 * VAR_0->cdlms[VAR_1][VAR_2].order); memcpy(VAR_0->cdlms[VAR_1][VAR_2].lms_updates + VAR_0->cdlms[VAR_1][VAR_2].order,
VAR_0->cdlms[VAR_1][VAR_2].lms_updates,
VAR_6 * VAR_0->cdlms[VAR_1][VAR_2].order); VAR_0->cdlms[VAR_1][VAR_2].VAR_5 = VAR_0->cdlms[VAR_1][VAR_2].order; } }