From f7813a5324be39d13ab536c245d15dfc602a7849 Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Sun, 29 Dec 2013 12:19:38 +0000 Subject: basic type mechanism working --- ffmpeg/libavcodec/atrac.c | 82 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 18 deletions(-) (limited to 'ffmpeg/libavcodec/atrac.c') diff --git a/ffmpeg/libavcodec/atrac.c b/ffmpeg/libavcodec/atrac.c index ea342a0..12e8997 100644 --- a/ffmpeg/libavcodec/atrac.c +++ b/ffmpeg/libavcodec/atrac.c @@ -1,6 +1,7 @@ /* - * 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 FFmpeg. @@ -44,11 +45,7 @@ static const float qmf_48tap_half[24] = { -0.043596379, -0.099384367, 0.13207909, 0.46424159 }; -/** - * Generate common tables - */ - -void ff_atrac_generate_tables(void) +av_cold void ff_atrac_generate_tables(void) { int i; float s; @@ -66,20 +63,69 @@ void ff_atrac_generate_tables(void) } } +av_cold void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset, + int loc_scale) +{ + int i; -/** - * 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 - */ + 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->lev_code[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->loc_code[i] << gctx->loc_scale; + + lev = gctx->gain_tab1[gc_now->lev_code[i]]; + gain_inc = gctx->gain_tab2[(i + 1 < gc_now->num_points ? gc_now->lev_code[i + 1] + : gctx->id2exp_offset) - + gc_now->lev_code[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 the 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) +void ff_atrac_iqmf(float *inlo, float *inhi, unsigned int nIn, float *pOut, + float *delayBuf, float *temp) { int i, j; float *p1, *p3; -- cgit v1.2.3