summaryrefslogtreecommitdiff
path: root/libavcodec/alac.c
diff options
context:
space:
mode:
authorJustin Ruggles <justin.ruggles@gmail.com>2012-07-19 14:08:22 -0400
committerJustin Ruggles <justin.ruggles@gmail.com>2012-07-27 13:52:19 -0400
commitfb57e913e196b26b4ee6ede90f06821e2be7e28a (patch)
tree030dbb55e4f94bc3d9c6347930e6d75cebe0903e /libavcodec/alac.c
parent2f096bb10e0584397a08b418fdfa7ecc862ebfa0 (diff)
alac: reverse lpc coeff order, simplify filter
Reversing the lpc coefficient order simplifies indexing in the filter.
Diffstat (limited to 'libavcodec/alac.c')
-rw-r--r--libavcodec/alac.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/libavcodec/alac.c b/libavcodec/alac.c
index aa2e6c8a3c..1756cdf888 100644
--- a/libavcodec/alac.c
+++ b/libavcodec/alac.c
@@ -194,6 +194,7 @@ static void lpc_prediction(int32_t *error_buffer, int32_t *buffer_out,
int lpc_order, int lpc_quant)
{
int i;
+ int32_t *pred = buffer_out;
/* first sample always copies */
*buffer_out = *error_buffer;
@@ -217,37 +218,35 @@ static void lpc_prediction(int32_t *error_buffer, int32_t *buffer_out,
}
/* read warm-up samples */
- for (i = 0; i < lpc_order; i++) {
- buffer_out[i + 1] = sign_extend(buffer_out[i] + error_buffer[i + 1],
- bps);
- }
+ for (i = 1; i <= lpc_order; i++)
+ buffer_out[i] = sign_extend(buffer_out[i - 1] + error_buffer[i], bps);
/* NOTE: 4 and 8 are very common cases that could be optimized. */
- for (i = lpc_order; i < nb_samples - 1; i++) {
+ for (; i < nb_samples; i++) {
int j;
int val = 0;
- int error_val = error_buffer[i + 1];
+ int error_val = error_buffer[i];
int error_sign;
- int d = buffer_out[i - lpc_order];
+ int d = *pred++;
/* LPC prediction */
for (j = 0; j < lpc_order; j++)
- val += (buffer_out[i - j] - d) * lpc_coefs[j];
+ val += (pred[j] - d) * lpc_coefs[j];
val = (val + (1 << (lpc_quant - 1))) >> lpc_quant;
val += d + error_val;
- buffer_out[i + 1] = sign_extend(val, bps);
+ buffer_out[i] = sign_extend(val, bps);
/* adapt LPC coefficients */
error_sign = sign_only(error_val);
if (error_sign) {
- for (j = lpc_order - 1; j >= 0 && error_val * error_sign > 0; j--) {
+ for (j = 0; j < lpc_order && error_val * error_sign > 0; j++) {
int sign;
- val = d - buffer_out[i - j];
+ val = d - pred[j];
sign = sign_only(val) * error_sign;
lpc_coefs[j] -= sign;
val *= sign;
- error_val -= (val >> lpc_quant) * (lpc_order - j);
+ error_val -= (val >> lpc_quant) * (j + 1);
}
}
}
@@ -350,7 +349,7 @@ static int decode_element(AVCodecContext *avctx, void *data, int ch_index,
lpc_order[ch] = get_bits(&alac->gb, 5);
/* read the predictor table */
- for (i = 0; i < lpc_order[ch]; i++)
+ for (i = lpc_order[ch] - 1; i >= 0; i--)
lpc_coefs[ch][i] = get_sbits(&alac->gb, 16);
}