[soc]: r5408 - in als: als_data.h alsdec.c
Author: thilo.borgmann Date: Tue Oct 13 21:35:21 2009 New Revision: 5408 Log: Added long-term prediction. Modified: als/als_data.h als/alsdec.c Modified: als/als_data.h ============================================================================== --- als/als_data.h Tue Oct 13 21:29:01 2009 (r5407) +++ als/als_data.h Tue Oct 13 21:35:21 2009 (r5408) @@ -92,4 +92,11 @@ static const int16_t parcor_scaled_value }; +/** Gain values of p(0) for long-term prediction. + * To be indexed by the Rice coded indices. + */ +static const int ltp_gain [] = { + 0, 8, 16, 24, 32, 40, 48, 56, 64, 70, 76, 82, 88, 92, 96, 100 +}; + #endif /* AVCODEC_ALS_DATA_H */ Modified: als/alsdec.c ============================================================================== --- als/alsdec.c Tue Oct 13 21:29:01 2009 (r5407) +++ als/alsdec.c Tue Oct 13 21:35:21 2009 (r5408) @@ -79,6 +79,7 @@ typedef struct { unsigned int frame_id; ///< the frame ID / number of the current frame unsigned int js_switch; ///< if true, joint-stereo decoding is enforced unsigned int num_blocks; ///< number of blocks used in the current frame + int ltp_lag_length; ///< number of bits used for ltp lag value int32_t *quant_cof; ///< quantized parcor coefficients int32_t *lpc_cof; ///< coefficients of the direct form prediction filter int32_t *prev_raw_samples; ///< contains unshifted raw samples from the previous block @@ -290,7 +291,6 @@ static int check_specific_config(ALSDecC } MISSING_ERR(sconf->floating, "Floating point decoding", -1); - MISSING_ERR(sconf->long_term_prediction, "Long-term prediction", -1); MISSING_ERR(sconf->bgmc, "BGMC entropy decoding", -1); MISSING_ERR(sconf->mc_coding, "Multi-channel correlation", -1); MISSING_ERR(sconf->rlslms, "Adaptive RLS-LMS prediction", -1); @@ -470,6 +470,9 @@ static int read_var_block(ALSDecContext int smp = 0; int sb, store_prev_samples; int64_t y; + int use_ltp = 0; + int lag = 0; + int gain[5]; *js_blocks = get_bits1(gb); @@ -568,7 +571,26 @@ static int read_var_block(ALSDecContext } } - // TODO: LTP mode + // read LTP gain and lag values + if (sconf->long_term_prediction) { + use_ltp = get_bits1(gb); + + if (use_ltp) { + gain[0] = decode_rice(gb, 1) << 3; + gain[1] = decode_rice(gb, 2) << 3; + + gain[2] = get_unary(gb, 0, 4); + gain[2] <<= 2; + gain[2] += get_bits(gb, 2); + gain[2] = ltp_gain[gain[2]]; + + gain[3] = decode_rice(gb, 2) << 3; + gain[4] = decode_rice(gb, 1) << 3; + + lag = get_bits(gb, ctx->ltp_lag_length); + lag += FFMAX(4, opt_order + 1); + } + } // read first value and residuals in case of a random access block if (ra_block) { @@ -593,6 +615,26 @@ static int read_var_block(ALSDecContext *current_res++ = decode_rice(gb, s[sb]); } + // revert long-term prediction + if (use_ltp) { + int ltp_smp; + + for (ltp_smp = 0; ltp_smp < block_length; ltp_smp++) { + int center = ltp_smp - lag; + int begin = FFMAX(0, center - 2); + int end = center + 3; + int tab = 5 - (end - begin); + int base; + + y = 1 << 6; + + for (base = begin; base < end; base++, tab++) + y += MUL64(gain[tab], raw_samples[base]); + + raw_samples[ltp_smp] += y >> 7; + } + } + // reconstruct all samples from residuals if (ra_block) { for (smp = 0; smp < opt_order; smp++) { @@ -974,6 +1016,14 @@ static av_cold int decode_init(AVCodecCo avctx->bits_per_raw_sample = (sconf->resolution + 1) * 8; } + // set lag value for long-term prediction + if (avctx->sample_rate >= 192000) + ctx->ltp_lag_length = 10; + else if (avctx->sample_rate >= 96000) + ctx->ltp_lag_length = 9; + else + ctx->ltp_lag_length = 8; + avctx->frame_size = sconf->frame_length; channel_size = sconf->frame_length + sconf->max_order;
thilo.borgmann wrote:
Author: thilo.borgmann Date: Tue Oct 13 21:35:21 2009 New Revision: 5408
Log: Added long-term prediction.
Modified: als/als_data.h als/alsdec.c
Modified: als/als_data.h ============================================================================== --- als/als_data.h Tue Oct 13 21:29:01 2009 (r5407) +++ als/als_data.h Tue Oct 13 21:35:21 2009 (r5408) @@ -92,4 +92,11 @@ static const int16_t parcor_scaled_value };
+/** Gain values of p(0) for long-term prediction. + * To be indexed by the Rice coded indices. + */ +static const int ltp_gain [] = { + 0, 8, 16, 24, 32, 40, 48, 56, 64, 70, 76, 82, 88, 92, 96, 100 +};
uint8_t
+ #endif /* AVCODEC_ALS_DATA_H */
Modified: als/alsdec.c ============================================================================== --- als/alsdec.c Tue Oct 13 21:29:01 2009 (r5407) +++ als/alsdec.c Tue Oct 13 21:35:21 2009 (r5408) @@ -79,6 +79,7 @@ typedef struct { unsigned int frame_id; ///< the frame ID / number of the current frame unsigned int js_switch; ///< if true, joint-stereo decoding is enforced unsigned int num_blocks; ///< number of blocks used in the current frame + int ltp_lag_length; ///< number of bits used for ltp lag value int32_t *quant_cof; ///< quantized parcor coefficients int32_t *lpc_cof; ///< coefficients of the direct form prediction filter int32_t *prev_raw_samples; ///< contains unshifted raw samples from the previous block @@ -290,7 +291,6 @@ static int check_specific_config(ALSDecC }
MISSING_ERR(sconf->floating, "Floating point decoding", -1); - MISSING_ERR(sconf->long_term_prediction, "Long-term prediction", -1); MISSING_ERR(sconf->bgmc, "BGMC entropy decoding", -1); MISSING_ERR(sconf->mc_coding, "Multi-channel correlation", -1); MISSING_ERR(sconf->rlslms, "Adaptive RLS-LMS prediction", -1); @@ -470,6 +470,9 @@ static int read_var_block(ALSDecContext int smp = 0; int sb, store_prev_samples; int64_t y; + int use_ltp = 0; + int lag = 0; + int gain[5];
for clarity, you should maybe call those ltp_lag and ltp_gain.
*js_blocks = get_bits1(gb);
@@ -568,7 +571,26 @@ static int read_var_block(ALSDecContext } }
- // TODO: LTP mode + // read LTP gain and lag values + if (sconf->long_term_prediction) { + use_ltp = get_bits1(gb); + + if (use_ltp) { + gain[0] = decode_rice(gb, 1) << 3; + gain[1] = decode_rice(gb, 2) << 3; + + gain[2] = get_unary(gb, 0, 4); + gain[2] <<= 2; + gain[2] += get_bits(gb, 2); + gain[2] = ltp_gain[gain[2]]; + + gain[3] = decode_rice(gb, 2) << 3; + gain[4] = decode_rice(gb, 1) << 3; + + lag = get_bits(gb, ctx->ltp_lag_length); + lag += FFMAX(4, opt_order + 1); + } + }
// read first value and residuals in case of a random access block if (ra_block) { @@ -593,6 +615,26 @@ static int read_var_block(ALSDecContext *current_res++ = decode_rice(gb, s[sb]); }
+ // revert long-term prediction
I would use "reverse" or "inverse" instead of "revert".
+ if (use_ltp) { + int ltp_smp; + + for (ltp_smp = 0; ltp_smp < block_length; ltp_smp++) { + int center = ltp_smp - lag; + int begin = FFMAX(0, center - 2); + int end = center + 3; + int tab = 5 - (end - begin); + int base; + + y = 1 << 6; + + for (base = begin; base < end; base++, tab++) + y += MUL64(gain[tab], raw_samples[base]); + + raw_samples[ltp_smp] += y >> 7; + } + }
Maybe you could calculate the point where begin < end so that you don't have a lot of unneeded raw_samples[ltp_smp] += 0. Good job. I assume it works with conformance test samples? -Justin
+ if (use_ltp) { + int ltp_smp; + + for (ltp_smp = 0; ltp_smp < block_length; ltp_smp++) { + int center = ltp_smp - lag; + int begin = FFMAX(0, center - 2); + int end = center + 3; + int tab = 5 - (end - begin); + int base; + + y = 1 << 6; + + for (base = begin; base < end; base++, tab++) + y += MUL64(gain[tab], raw_samples[base]); + + raw_samples[ltp_smp] += y >> 7; + } + }
Maybe you could calculate the point where begin < end so that you don't have a lot of unneeded raw_samples[ltp_smp] += 0.
Good point. Done!
Good job. I assume it works with conformance test samples?
With the conformance as well as my own test files, yes. Thanks! -Thilo
participants (3)
-
Justin Ruggles -
Thilo Borgmann -
thilo.borgmann