1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-26 19:01:44 +02:00

Implement lms_update()

This commit is contained in:
Mashiat Sarker Shakkhar 2011-11-06 03:02:41 +06:00
parent 0faae518e9
commit 269a0dee19

View File

@ -771,6 +771,55 @@ static int lms_predict(WmallDecodeCtx *s, int ich, int ilms)
return pred;
}
static void lms_update(WmallDecodeCtx *s, int ich, int ilms, int32_t input, int32_t pred)
{
int icoef;
int recent = s->cdlms[ich][ilms].recent;
int 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;
}
}
/**
*@brief Decode a single subframe (block).
*@param s codec context