@Derek && @Diego: Thank you for the review! Please find attached the updated patch.
Best regards Maxim
>From 085cfcbfeada7736c54406573e5fe2c56ab11016 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski <[email protected]> Date: Mon, 30 Sep 2013 23:14:51 +0200 Subject: [PATCH 1/2] atrac cosmetics: move doxygen comments to the header file, break long lines, improve file description and update copyright messages. --- libavcodec/atrac.c | 24 ++++-------------------- libavcodec/atrac.h | 23 +++++++++++++++++++---- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/libavcodec/atrac.c b/libavcodec/atrac.c index 6041a12..de2f131 100644 --- a/libavcodec/atrac.c +++ b/libavcodec/atrac.c @@ -1,6 +1,6 @@ /* - * ATRAC common functions - * Copyright (c) 2006-2008 Maxim Poliakovski + * Common functions for the ATRAC family of decoders + * Copyright (c) 2006-2013 Maxim Poliakovski * Copyright (c) 2006-2008 Benjamin Larsson * * This file is part of Libav. @@ -44,10 +44,6 @@ static const float qmf_48tap_half[24] = { -0.043596379, -0.099384367, 0.13207909, 0.46424159 }; -/** - * Generate common tables - */ - void ff_atrac_generate_tables(void) { int i; @@ -66,20 +62,8 @@ void ff_atrac_generate_tables(void) } } - -/** - * Quadrature mirror synthesis filter. - * - * @param inlo lower part of spectrum - * @param inhi higher part of spectrum - * @param nIn size of spectrum buffer - * @param pOut out buffer - * @param delayBuf delayBuf buffer - * @param temp temp buffer - */ - - -void ff_atrac_iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, float *delayBuf, float *temp) +void ff_atrac_iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, + float *delayBuf, float *temp) { int i, j; float *p1, *p3; diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h index 8e9ba59..6067f18 100644 --- a/libavcodec/atrac.h +++ b/libavcodec/atrac.h @@ -1,7 +1,7 @@ /* - * ATRAC common data - * Copyright (c) 2009 Maxim Poliakovski - * Copyright (c) 2009 Benjamin Larsson + * Common functions for the ATRAC family of decoders + * Copyright (c) 2009-2013 Maxim Poliakovski + * Copyright (c) 2009 Benjamin Larsson * * This file is part of Libav. * @@ -30,7 +30,22 @@ extern float ff_atrac_sf_table[64]; +/** + * Generate common tables. + */ void ff_atrac_generate_tables(void); -void ff_atrac_iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, float *delayBuf, float *temp); + +/** + * Quadrature mirror synthesis filter. + * + * @param inlo lower part of spectrum + * @param inhi higher part of spectrum + * @param nIn size of spectrum buffer + * @param pOut out buffer + * @param delayBuf delayBuf buffer + * @param temp temp buffer + */ +void ff_atrac_iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, + float *delayBuf, float *temp); #endif /* AVCODEC_ATRAC_H */ -- 1.7.9.5
>From aade9868608a65231a57dd36f203a647a9db906b Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski <[email protected]> Date: Tue, 1 Oct 2013 00:58:41 +0200 Subject: [PATCH 2/2] atrac3: Generalize gain compensation code Move it to atrac.c, so it can be reused within the upcoming ATRAC3+ decoder. --- libavcodec/atrac.c | 60 ++++++++++++++++++++++++++++++ libavcodec/atrac.h | 45 ++++++++++++++++++++++ libavcodec/atrac3.c | 103 ++++++++++----------------------------------------- 3 files changed, 125 insertions(+), 83 deletions(-) diff --git a/libavcodec/atrac.c b/libavcodec/atrac.c index de2f131..59e4c0e 100644 --- a/libavcodec/atrac.c +++ b/libavcodec/atrac.c @@ -62,6 +62,66 @@ void ff_atrac_generate_tables(void) } } +av_cold void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset, + int loc_scale) +{ + int i; + + gctx->loc_scale = loc_scale; + gctx->loc_size = 1 << loc_scale; + gctx->id2exp_offset = id2exp_offset; + + /* Generate gain level table. */ + for (i = 0; i < 16; i++) + gctx->gain_tab1[i] = powf(2.0, id2exp_offset - i); + + /* Generate gain interpolation table. */ + for (i = -15; i < 16; i++) + gctx->gain_tab2[i + 15] = powf(2.0, -1.0f / gctx->loc_size * i); +} + +void ff_atrac_gain_compensation(AtracGCContext *gctx, float *in, float *prev, + AtracGainInfo *gc_now, AtracGainInfo *gc_next, + int num_samples, float *out) +{ + float lev, gc_scale, gain_inc; + int i, pos, lastpos; + + gc_scale = gc_next->num_points ? gctx->gain_tab1[gc_next->levcode[0]] : 1.0f; + + if (!gc_now->num_points) { + for (pos = 0; pos < num_samples; pos++) + out[pos] = in[pos] * gc_scale + prev[pos]; + } else { + pos = 0; + + for (i = 0; i < gc_now->num_points; i++) { + lastpos = gc_now->loccode[i] << gctx->loc_scale; + + lev = gctx->gain_tab1[gc_now->levcode[i]]; + gain_inc = gctx->gain_tab2[(i + 1 < gc_now->num_points ? + gc_now->levcode[i + 1] : gctx->id2exp_offset) + - gc_now->levcode[i] + 15]; + + /* apply constant gain level and overlap */ + for (; pos < lastpos; pos++) + out[pos] = (in[pos] * gc_scale + prev[pos]) * lev; + + /* interpolate between two different gain levels */ + for (; pos < lastpos + gctx->loc_size; pos++) { + out[pos] = (in[pos] * gc_scale + prev[pos]) * lev; + lev *= gain_inc; + } + } + + for (; pos < num_samples; pos++) + out[pos] = in[pos] * gc_scale + prev[pos]; + } + + /* copy the overlapping part into delay buffer */ + memcpy(prev, &in[num_samples], num_samples * sizeof(float)); +} + void ff_atrac_iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, float *delayBuf, float *temp) { diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h index 6067f18..d9177fb 100644 --- a/libavcodec/atrac.h +++ b/libavcodec/atrac.h @@ -28,6 +28,26 @@ #ifndef AVCODEC_ATRAC_H #define AVCODEC_ATRAC_H +/** + * Gain control parameters for one subband. + */ +typedef struct AtracGainInfo { + int num_points; ///< number of gain control points + int levcode[7]; ///< level at corresponding control point + int loccode[7]; ///< location of gain control points +} AtracGainInfo; + +/** + * Gain compensation context structure. + */ +typedef struct AtracGCContext { + float gain_tab1[16]; ///< gain compensation level table + float gain_tab2[31]; ///< gain compensation interpolation table + int id2exp_offset; ///< offset for converting level index into level exponent + int loc_scale; ///< scale of location code = 2^loc_scale samples + int loc_size; ///< size of location code in samples +} AtracGCContext; + extern float ff_atrac_sf_table[64]; /** @@ -36,6 +56,31 @@ extern float ff_atrac_sf_table[64]; void ff_atrac_generate_tables(void); /** + * Initialize gain compensation context. + * + * @param gctx pointer to gain compensation context to initialize + * @param id2exp_offset offset for converting level index into level exponent + * @param loc_scale location size factor + */ +void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset, + int loc_scale); + +/* + * Apply gain compensation and perform the MDCT overlapping part. + * + * @param gctx pointer to gain compensation context + * @param in input buffer + * @param prev previous buffer to perform overlap against + * @param gc_now gain control information for current frame + * @param gc_next gain control information for next frame + * @param num_samples number of samples to process + * @param out output data goes here + */ +void ff_atrac_gain_compensation(AtracGCContext *gctx, float *in, float *prev, + AtracGainInfo *gc_now, AtracGainInfo *gc_next, + int num_samples, float *out); + +/** * Quadrature mirror synthesis filter. * * @param inlo lower part of spectrum diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 1cb7b2b..643521e 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,90 +412,32 @@ static int decode_tonal_components(GetBitContext *gb, static int decode_gain_control(GetBitContext *gb, GainBlock *block, int num_bands) { - int i, cf, num_data; + int i, b; 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; - level = gain[i].lev_code; - loc = gain[i].loc_code; + for (b = 0; b <= num_bands; b++) { + gain[b].num_points = get_bits(gb, 3); + level = gain[b].levcode; + loc = gain[b].loccode; - for (cf = 0; cf < gain[i].num_gain_data; cf++) { - level[cf] = get_bits(gb, 4); - loc [cf] = get_bits(gb, 5); - if (cf && loc[cf] <= loc[cf - 1]) + for (i = 0; i < gain[b].num_points; i++) { + level[i] = get_bits(gb, 4); + loc [i] = get_bits(gb, 5); + if (i && loc[i] <= loc[i-1]) return AVERROR_INVALIDDATA; } } - /* Clear the unused blocks. */ - for (; i < 4 ; i++) - gain[i].num_gain_data = 0; + /* Clear unused blocks. */ + for (; b < 4 ; b++) + gain[b].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); -- 1.7.9.5
_______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
