diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 36d2928137..30fe41618d 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -315,6 +315,33 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, return 0; } +static void lpc_analyze_remodulate(int32_t *decoded, const int coeffs[32], + int order, int qlevel, int len, int bps) +{ + int i, j; + int ebps = 1 << (bps-1); + unsigned sigma = 0; + + for (i = order; i < len; i++) + sigma |= decoded[i] + ebps; + + if (sigma < 2*ebps) + return; + + for (i = len - 1; i >= order; i--) { + int64_t p = 0; + for (j = 0; j < order; j++) + p += coeffs[j] * (int64_t)decoded[i-order+j]; + decoded[i] -= p >> qlevel; + } + for (i = order; i < len; i++, decoded++) { + int32_t p = 0; + for (j = 0; j < order; j++) + p += coeffs[j] * (uint32_t)decoded[j]; + decoded[j] += p >> qlevel; + } +} + static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order, int bps) { @@ -352,6 +379,8 @@ static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order, s->dsp.lpc16(decoded, coeffs, pred_order, qlevel, s->blocksize); } else { s->dsp.lpc32(decoded, coeffs, pred_order, qlevel, s->blocksize); + if (s->flac_stream_info.bps <= 16) + lpc_analyze_remodulate(decoded, coeffs, pred_order, qlevel, s->blocksize, bps); } return 0;