diff options
author | Vladimir Voroshilov <voroshil@gmail.com> | 2009-06-28 21:01:23 +0700 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-09-24 21:11:01 +0200 |
commit | 682337672cd38b8e85acf11578a5130fa87ea1d7 (patch) | |
tree | 9f667e00a6f95bce67f65cb466690939c69ad1a0 /libavcodec/g729dec.c | |
parent | aca516cd676f5646004c649dc614760b937f4624 (diff) | |
download | ffmpeg-682337672cd38b8e85acf11578a5130fa87ea1d7.tar.gz |
Adaptive gain control
Diffstat (limited to 'libavcodec/g729dec.c')
-rw-r--r-- | libavcodec/g729dec.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/libavcodec/g729dec.c b/libavcodec/g729dec.c index bc7fbc13a8..e977e53954 100644 --- a/libavcodec/g729dec.c +++ b/libavcodec/g729dec.c @@ -145,6 +145,7 @@ typedef struct { int16_t onset; ///< detected onset level (0-2) int16_t was_periodic; ///< whether previous frame was declared as periodic or not (4.4) int16_t ht_prev_data; ///< previous data for 4.2.3, equation 86 + int gain_coeff; ///< (1.14) gain coefficient (4.2.4) uint16_t rand_value; ///< random number generator value (4.4.4) int ma_predictor_prev; ///< switched MA predictor of LSP quantizer from last good frame @@ -348,6 +349,8 @@ static av_cold int decoder_init(AVCodecContext * avctx) /* Both 8kbit/s and 6.4kbit/s modes uses two subframes per frame. */ avctx->frame_size = SUBFRAME_SIZE << 1; + ctx->gain_coeff = 16384; // 1.0 in (1.14) + for (k = 0; k < MA_NP + 1; k++) { ctx->past_quantizer_outputs[k] = ctx->past_quantizer_output_buf[k]; for (i = 1; i < 11; i++) @@ -397,6 +400,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, int16_t fc[SUBFRAME_SIZE]; // fixed-codebook vector int16_t synth[SUBFRAME_SIZE+10]; // fixed-codebook vector int j; + int gain_before, gain_after; int is_periodic = 0; // whether one of the subframes is declared as periodic or not if (*data_size < SUBFRAME_SIZE << 2) { @@ -637,6 +641,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, /* Save data (without postfilter) for use in next subframe. */ memcpy(ctx->syn_filter_data, synth+SUBFRAME_SIZE, 10 * sizeof(int16_t)); + /* Calculate gain of unfiltered signal for use in AGC. */ + gain_before = 0; + for (j = 0; j < SUBFRAME_SIZE; j++) + gain_before += FFABS(synth[j+10]); + /* Call postfilter and also update voicing decision for use in next frame. */ g729_postfilter( &ctx->dsp, @@ -650,6 +659,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, synth+10, SUBFRAME_SIZE); + /* Calculate gain of filtered signal for use in AGC. */ + gain_after = 0; + for(j=0; j<SUBFRAME_SIZE; j++) + gain_after += FFABS(synth[j+10]); + + ctx->gain_coeff = g729_adaptive_gain_control( + gain_before, + gain_after, + synth+10, + SUBFRAME_SIZE, + ctx->gain_coeff); + if (frame_erasure) ctx->pitch_delay_int_prev = FFMIN(ctx->pitch_delay_int_prev + 1, PITCH_DELAY_MAX); else |