aacpsy.c 11.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * AAC encoder psychoacoustic model
 * Copyright (C) 2008 Konstantin Shishkov
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
23
 * @file
24 25 26 27 28
 * AAC encoder psychoacoustic model
 */

#include "avcodec.h"
#include "aactab.h"
29
#include "psymodel.h"
30 31 32 33 34 35 36 37 38 39 40 41 42 43

/***********************************
 *              TODOs:
 * thresholds linearization after their modifications for attaining given bitrate
 * try other bitrate controlling mechanism (maybe use ratecontrol.c?)
 * control quality for quality-based output
 **********************************/

/**
 * constants for 3GPP AAC psychoacoustic model
 * @{
 */
#define PSY_3GPP_SPREAD_LOW  1.5f // spreading factor for ascending threshold spreading  (15 dB/Bark)
#define PSY_3GPP_SPREAD_HI   3.0f // spreading factor for descending threshold spreading (30 dB/Bark)
44 45 46

#define PSY_3GPP_RPEMIN      0.01f
#define PSY_3GPP_RPELEV      2.0f
47 48 49 50 51 52 53 54 55 56
/**
 * @}
 */

/**
 * information for single band used by 3GPP TS26.403-inspired psychoacoustic model
 */
typedef struct Psy3gppBand{
    float energy;    ///< band energy
    float ffac;      ///< form factor
57 58 59
    float thr;       ///< energy threshold
    float min_snr;   ///< minimal SNR
    float thr_quiet; ///< threshold in quiet
60 61
}Psy3gppBand;

62 63 64 65 66 67 68 69 70 71 72 73 74
/**
 * single/pair channel context for psychoacoustic model
 */
typedef struct Psy3gppChannel{
    Psy3gppBand band[128];               ///< bands information
    Psy3gppBand prev_band[128];          ///< bands information from the previous frame

    float       win_energy;              ///< sliding average of channel energy
    float       iir_state[2];            ///< hi-pass IIR filter state
    uint8_t     next_grouping;           ///< stored grouping scheme for the next frame (in case of 8 short window sequence)
    enum WindowSequence next_window_seq; ///< window sequence to be used in the next frame
}Psy3gppChannel;

75 76 77 78 79 80 81 82 83 84
/**
 * psychoacoustic model frame type-dependent coefficients
 */
typedef struct Psy3gppCoeffs{
    float ath       [64]; ///< absolute threshold of hearing per bands
    float barks     [64]; ///< Bark value for each spectral band in long frame
    float spread_low[64]; ///< spreading factor for low-to-high threshold spreading in long frame
    float spread_hi [64]; ///< spreading factor for high-to-low threshold spreading in long frame
}Psy3gppCoeffs;

85 86 87 88 89 90 91 92
/**
 * 3GPP TS26.403-inspired psychoacoustic model specific data
 */
typedef struct Psy3gppContext{
    Psy3gppCoeffs psy_coef[2];
    Psy3gppChannel *ch;
}Psy3gppContext;

93 94 95
/**
 * Calculate Bark value for given line.
 */
96
static av_cold float calc_bark(float f)
97 98 99
{
    return 13.3f * atanf(0.00076f * f) + 3.5f * atanf((f / 7500.0f) * (f / 7500.0f));
}
100 101 102 103 104 105 106 107 108

#define ATH_ADD 4
/**
 * Calculate ATH value for given frequency.
 * Borrowed from Lame.
 */
static av_cold float ath(float f, float add)
{
    f /= 1000.0f;
109
    return    3.64 * pow(f, -0.8)
110 111 112 113 114
            - 6.8  * exp(-0.6  * (f - 3.4) * (f - 3.4))
            + 6.0  * exp(-0.15 * (f - 8.7) * (f - 8.7))
            + (0.6 + 0.04 * add) * 0.001 * f * f * f * f;
}

115
static av_cold int psy_3gpp_init(FFPsyContext *ctx) {
116
    Psy3gppContext *pctx;
117
    float bark;
118 119 120 121 122 123 124
    int i, j, g, start;
    float prev, minscale, minath;

    ctx->model_priv_data = av_mallocz(sizeof(Psy3gppContext));
    pctx = (Psy3gppContext*) ctx->model_priv_data;

    minath = ath(3410, ATH_ADD);
125
    for (j = 0; j < 2; j++) {
126 127 128
        Psy3gppCoeffs *coeffs = &pctx->psy_coef[j];
        i = 0;
        prev = 0.0;
129
        for (g = 0; g < ctx->num_bands[j]; g++) {
130
            i += ctx->bands[j][g];
131 132 133
            bark = calc_bark((i-1) * ctx->avctx->sample_rate / 2048.0);
            coeffs->barks[g] = (bark + prev) / 2.0;
            prev = bark;
134
        }
135
        for (g = 0; g < ctx->num_bands[j] - 1; g++) {
136 137 138 139
            coeffs->spread_low[g] = pow(10.0, -(coeffs->barks[g+1] - coeffs->barks[g]) * PSY_3GPP_SPREAD_LOW);
            coeffs->spread_hi [g] = pow(10.0, -(coeffs->barks[g+1] - coeffs->barks[g]) * PSY_3GPP_SPREAD_HI);
        }
        start = 0;
140
        for (g = 0; g < ctx->num_bands[j]; g++) {
141
            minscale = ath(ctx->avctx->sample_rate * start / 1024.0 / 2.0, ATH_ADD);
142
            for (i = 1; i < ctx->bands[j][g]; i++)
143
                minscale = FFMIN(minscale, ath(ctx->avctx->sample_rate * (start + i) / 1024.0 / 2.0, ATH_ADD));
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
            coeffs->ath[g] = minscale - minath;
            start += ctx->bands[j][g];
        }
    }

    pctx->ch = av_mallocz(sizeof(Psy3gppChannel) * ctx->avctx->channels);
    return 0;
}

/**
 * IIR filter used in block switching decision
 */
static float iir_filter(int in, float state[2])
{
    float ret;

    ret = 0.7548f * (in - state[0]) + 0.5095f * state[1];
    state[0] = in;
    state[1] = ret;
    return ret;
}

/**
 * window grouping information stored as bits (0 - new group, 1 - group continues)
 */
static const uint8_t window_grouping[9] = {
    0xB6, 0x6C, 0xD8, 0xB2, 0x66, 0xC6, 0x96, 0x36, 0x36
};

/**
 * Tell encoder which window types to use.
 * @see 3GPP TS26.403 5.4.1 "Blockswitching"
 */
static FFPsyWindowInfo psy_3gpp_window(FFPsyContext *ctx,
                                       const int16_t *audio, const int16_t *la,
                                       int channel, int prev_type)
{
    int i, j;
182 183
    int br               = ctx->avctx->bit_rate / ctx->avctx->channels;
    int attack_ratio     = br <= 16000 ? 18 : 10;
184
    Psy3gppContext *pctx = (Psy3gppContext*) ctx->model_priv_data;
185 186
    Psy3gppChannel *pch  = &pctx->ch[channel];
    uint8_t grouping     = 0;
187
    int next_type        = pch->next_window_seq;
188 189 190
    FFPsyWindowInfo wi;

    memset(&wi, 0, sizeof(wi));
191
    if (la) {
192 193 194 195
        float s[8], v;
        int switch_to_eight = 0;
        float sum = 0.0, sum2 = 0.0;
        int attack_n = 0;
196
        int stay_short = 0;
197 198
        for (i = 0; i < 8; i++) {
            for (j = 0; j < 128; j++) {
Alex Converse's avatar
Alex Converse committed
199
                v = iir_filter(la[(i*128+j)*ctx->avctx->channels], pch->iir_state);
200 201
                sum += v*v;
            }
202
            s[i]  = sum;
203 204
            sum2 += sum;
        }
205 206
        for (i = 0; i < 8; i++) {
            if (s[i] > pch->win_energy * attack_ratio) {
207
                attack_n        = i + 1;
208 209 210 211 212 213 214
                switch_to_eight = 1;
                break;
            }
        }
        pch->win_energy = pch->win_energy*7/8 + sum2/64;

        wi.window_type[1] = prev_type;
215
        switch (prev_type) {
216 217
        case ONLY_LONG_SEQUENCE:
            wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE;
218
            next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE;
219 220 221 222
            break;
        case LONG_START_SEQUENCE:
            wi.window_type[0] = EIGHT_SHORT_SEQUENCE;
            grouping = pch->next_grouping;
223
            next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;
224 225
            break;
        case LONG_STOP_SEQUENCE:
226 227
            wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE;
            next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE;
228 229
            break;
        case EIGHT_SHORT_SEQUENCE:
230 231 232 233
            stay_short = next_type == EIGHT_SHORT_SEQUENCE || switch_to_eight;
            wi.window_type[0] = stay_short ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;
            grouping = next_type == EIGHT_SHORT_SEQUENCE ? pch->next_grouping : 0;
            next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;
234 235
            break;
        }
236

237
        pch->next_grouping = window_grouping[attack_n];
238
        pch->next_window_seq = next_type;
239 240
    } else {
        for (i = 0; i < 3; i++)
241 242 243 244 245
            wi.window_type[i] = prev_type;
        grouping = (prev_type == EIGHT_SHORT_SEQUENCE) ? window_grouping[0] : 0;
    }

    wi.window_shape   = 1;
246
    if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) {
247 248
        wi.num_windows = 1;
        wi.grouping[0] = 1;
249
    } else {
250 251
        int lastgrp = 0;
        wi.num_windows = 8;
252 253
        for (i = 0; i < 8; i++) {
            if (!((grouping >> i) & 1))
254 255 256 257 258 259 260 261 262 263 264
                lastgrp = i;
            wi.grouping[lastgrp]++;
        }
    }

    return wi;
}

/**
 * Calculate band thresholds as suggested in 3GPP TS26.403
 */
265 266
static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
                             const float *coefs, FFPsyWindowInfo *wi)
267 268
{
    Psy3gppContext *pctx = (Psy3gppContext*) ctx->model_priv_data;
269
    Psy3gppChannel *pch  = &pctx->ch[channel];
270 271
    int start = 0;
    int i, w, g;
272
    const int num_bands       = ctx->num_bands[wi->num_windows == 8];
273
    const uint8_t* band_sizes = ctx->bands[wi->num_windows == 8];
274
    Psy3gppCoeffs *coeffs     = &pctx->psy_coef[wi->num_windows == 8];
275 276

    //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation"
277 278
    for (w = 0; w < wi->num_windows*16; w += 16) {
        for (g = 0; g < num_bands; g++) {
279 280
            Psy3gppBand *band = &pch->band[w+g];
            band->energy = 0.0f;
281
            for (i = 0; i < band_sizes[g]; i++)
282 283
                band->energy += coefs[start+i] * coefs[start+i];
            band->energy *= 1.0f / (512*512);
284 285
            band->thr     = band->energy * 0.001258925f;
            start        += band_sizes[g];
286 287 288 289 290

            ctx->psy_bands[channel*PSY_MAX_BANDS+w+g].energy = band->energy;
        }
    }
    //modify thresholds - spread, threshold in quiet - 5.4.3 "Spreaded Energy Calculation"
291
    for (w = 0; w < wi->num_windows*16; w += 16) {
292
        Psy3gppBand *band = &pch->band[w];
293
        for (g = 1; g < num_bands; g++)
294
            band[g].thr = FFMAX(band[g].thr, band[g-1].thr * coeffs->spread_low[g-1]);
295
        for (g = num_bands - 2; g >= 0; g--)
296
            band[g].thr = FFMAX(band[g].thr, band[g+1].thr * coeffs->spread_hi [g]);
297
        for (g = 0; g < num_bands; g++) {
298
            band[g].thr_quiet = FFMAX(band[g].thr, coeffs->ath[g]);
299
            if (wi->num_windows != 8 && wi->window_type[1] != EIGHT_SHORT_SEQUENCE)
300 301
                band[g].thr_quiet = FFMAX(PSY_3GPP_RPEMIN*band[g].thr_quiet,
                                          FFMIN(band[g].thr_quiet,
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
                                          PSY_3GPP_RPELEV*pch->prev_band[w+g].thr_quiet));
            band[g].thr = FFMAX(band[g].thr, band[g].thr_quiet * 0.25);

            ctx->psy_bands[channel*PSY_MAX_BANDS+w+g].threshold = band[g].thr;
        }
    }
    memcpy(pch->prev_band, pch->band, sizeof(pch->band));
}

static av_cold void psy_3gpp_end(FFPsyContext *apc)
{
    Psy3gppContext *pctx = (Psy3gppContext*) apc->model_priv_data;
    av_freep(&pctx->ch);
    av_freep(&apc->model_priv_data);
}


const FFPsyModel ff_aac_psy_model =
{
    .name    = "3GPP TS 26.403-inspired model",
    .init    = psy_3gpp_init,
    .window  = psy_3gpp_window,
    .analyze = psy_3gpp_analyze,
    .end     = psy_3gpp_end,
};