diff options
author | Maxim Poliakovski <max_pole@gmx.de> | 2013-09-30 23:14:51 +0200 |
---|---|---|
committer | Diego Biurrun <diego@biurrun.de> | 2013-10-03 18:20:01 +0200 |
commit | 79cbac8cd456c3f1c914bd1e7262b55e48de13a7 (patch) | |
tree | a06c45e77b9f0e19acc69360084aa8227c2f3ebc /libavcodec/atrac3.c | |
parent | 5ce04c14dd3dd3670cbdba82275a3a72c716ec6f (diff) | |
download | ffmpeg-79cbac8cd456c3f1c914bd1e7262b55e48de13a7.tar.gz |
atrac3: Generalize gain compensation code
Move it to the ATRAC common code, to reuse in the upcoming ATRAC3+ decoder.
Signed-off-by: Diego Biurrun <diego@biurrun.de>
Diffstat (limited to 'libavcodec/atrac3.c')
-rw-r--r-- | libavcodec/atrac3.c | 87 |
1 files changed, 12 insertions, 75 deletions
diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 46aee65f10..5378d956d2 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -54,14 +54,8 @@ #define SAMPLES_PER_FRAME 1024 #define MDCT_SIZE 512 -typedef struct GainInfo { - int num_gain_data; - int lev_code[8]; - int loc_code[8]; -} GainInfo; - typedef struct GainBlock { - GainInfo g_block[4]; + AtracGainInfo g_block[4]; } GainBlock; typedef struct TonalComponent { @@ -111,6 +105,7 @@ typedef struct ATRAC3Context { int scrambled_stream; //@} + AtracGCContext gainc_ctx; FFTContext mdct_ctx; FmtConvertContext fmt_conv; AVFloatDSPContext fdsp; @@ -417,18 +412,17 @@ static int decode_tonal_components(GetBitContext *gb, static int decode_gain_control(GetBitContext *gb, GainBlock *block, int num_bands) { - int i, j, num_data; + int i, j; int *level, *loc; - GainInfo *gain = block->g_block; + AtracGainInfo *gain = block->g_block; for (i = 0; i <= num_bands; i++) { - num_data = get_bits(gb, 3); - gain[i].num_gain_data = num_data; + gain[i].num_points = get_bits(gb, 3); level = gain[i].lev_code; loc = gain[i].loc_code; - for (j = 0; j < gain[i].num_gain_data; j++) { + for (j = 0; j < gain[i].num_points; j++) { level[j] = get_bits(gb, 4); loc[j] = get_bits(gb, 5); if (j && loc[j] <= loc[j - 1]) @@ -438,69 +432,12 @@ static int decode_gain_control(GetBitContext *gb, GainBlock *block, /* Clear the unused blocks. */ for (; i < 4 ; i++) - gain[i].num_gain_data = 0; + gain[i].num_points = 0; return 0; } /** - * Apply gain parameters and perform the MDCT overlapping part - * - * @param input input buffer - * @param prev previous buffer to perform overlap against - * @param output output buffer - * @param gain1 current band gain info - * @param gain2 next band gain info - */ -static void gain_compensate_and_overlap(float *input, float *prev, - float *output, GainInfo *gain1, - GainInfo *gain2) -{ - float g1, g2, gain_inc; - int i, j, num_data, start_loc, end_loc; - - - if (gain2->num_gain_data == 0) - g1 = 1.0; - else - g1 = gain_tab1[gain2->lev_code[0]]; - - if (gain1->num_gain_data == 0) { - for (i = 0; i < 256; i++) - output[i] = input[i] * g1 + prev[i]; - } else { - num_data = gain1->num_gain_data; - gain1->loc_code[num_data] = 32; - gain1->lev_code[num_data] = 4; - - for (i = 0, j = 0; i < num_data; i++) { - start_loc = gain1->loc_code[i] * 8; - end_loc = start_loc + 8; - - g2 = gain_tab1[gain1->lev_code[i]]; - gain_inc = gain_tab2[gain1->lev_code[i + 1] - - gain1->lev_code[i ] + 15]; - - /* interpolate */ - for (; j < start_loc; j++) - output[j] = (input[j] * g1 + prev[j]) * g2; - - /* interpolation is done over eight samples */ - for (; j < end_loc; j++) { - output[j] = (input[j] * g1 + prev[j]) * g2; - g2 *= gain_inc; - } - } - - for (; j < 256; j++) - output[j] = input[j] * g1 + prev[j]; - } - - /* Delay for the overlapping part. */ - memcpy(prev, &input[256], 256 * sizeof(*prev)); -} - -/** * Combine the tonal band spectrum and regular band spectrum * * @param spectrum output spectrum buffer @@ -690,11 +627,10 @@ static int decode_channel_sound_unit(ATRAC3Context *q, GetBitContext *gb, memset(snd->imdct_buf, 0, 512 * sizeof(*snd->imdct_buf)); /* gain compensation and overlapping */ - gain_compensate_and_overlap(snd->imdct_buf, - &snd->prev_frame[band * 256], - &output[band * 256], - &gain1->g_block[band], - &gain2->g_block[band]); + ff_atrac_gain_compensation(&q->gainc_ctx, snd->imdct_buf, + &snd->prev_frame[band * 256], + &gain1->g_block[band], &gain2->g_block[band], + 256, &output[band * 256]); } /* Swap the gain control buffers for the next frame. */ @@ -982,6 +918,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) q->matrix_coeff_index_next[i] = 3; } + ff_atrac_init_gain_compensation(&q->gainc_ctx, 4, 3); avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); ff_fmt_convert_init(&q->fmt_conv, avctx); |