1025 lines · 38.9 KB · C
RawDownload
/* * 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 */ /** * @file * AAC encoder psychoacoustic model */ #include "libavutil/attributes.h"#include "libavutil/ffmath.h" #include "avcodec.h"#include "aactab.h"#include "psymodel.h" /*********************************** *              TODOs: * try other bitrate controlling mechanism (maybe use ratecontrol.c?) * control quality for quality-based output **********************************/ /** * constants for 3GPP AAC psychoacoustic model * @{ */#define PSY_3GPP_THR_SPREAD_HI   1.5f // spreading factor for low-to-hi threshold spreading  (15 dB/Bark)#define PSY_3GPP_THR_SPREAD_LOW  3.0f // spreading factor for hi-to-low threshold spreading  (30 dB/Bark)/* spreading factor for low-to-hi energy spreading, long block, > 22kbps/channel (20dB/Bark) */#define PSY_3GPP_EN_SPREAD_HI_L1 2.0f/* spreading factor for low-to-hi energy spreading, long block, <= 22kbps/channel (15dB/Bark) */#define PSY_3GPP_EN_SPREAD_HI_L2 1.5f/* spreading factor for low-to-hi energy spreading, short block (15 dB/Bark) */#define PSY_3GPP_EN_SPREAD_HI_S  1.5f/* spreading factor for hi-to-low energy spreading, long block (30dB/Bark) */#define PSY_3GPP_EN_SPREAD_LOW_L 3.0f/* spreading factor for hi-to-low energy spreading, short block (20dB/Bark) */#define PSY_3GPP_EN_SPREAD_LOW_S 2.0f #define PSY_3GPP_RPEMIN      0.01f#define PSY_3GPP_RPELEV      2.0f #define PSY_3GPP_C1          3.0f           /* log2(8) */#define PSY_3GPP_C2          1.3219281f     /* log2(2.5) */#define PSY_3GPP_C3          0.55935729f    /* 1 - C2 / C1 */ #define PSY_SNR_1DB          7.9432821e-1f  /* -1dB */#define PSY_SNR_25DB         3.1622776e-3f  /* -25dB */ #define PSY_3GPP_SAVE_SLOPE_L  -0.46666667f#define PSY_3GPP_SAVE_SLOPE_S  -0.36363637f#define PSY_3GPP_SAVE_ADD_L    -0.84285712f#define PSY_3GPP_SAVE_ADD_S    -0.75f#define PSY_3GPP_SPEND_SLOPE_L  0.66666669f#define PSY_3GPP_SPEND_SLOPE_S  0.81818181f#define PSY_3GPP_SPEND_ADD_L   -0.35f#define PSY_3GPP_SPEND_ADD_S   -0.26111111f#define PSY_3GPP_CLIP_LO_L      0.2f#define PSY_3GPP_CLIP_LO_S      0.2f#define PSY_3GPP_CLIP_HI_L      0.95f#define PSY_3GPP_CLIP_HI_S      0.75f #define PSY_3GPP_AH_THR_LONG    0.5f#define PSY_3GPP_AH_THR_SHORT   0.63f #define PSY_PE_FORGET_SLOPE  511 enum {    PSY_3GPP_AH_NONE,    PSY_3GPP_AH_INACTIVE,    PSY_3GPP_AH_ACTIVE}; #define PSY_3GPP_BITS_TO_PE(bits) ((bits) * 1.18f)#define PSY_3GPP_PE_TO_BITS(bits) ((bits) / 1.18f) /* LAME psy model constants */#define PSY_LAME_FIR_LEN 21         ///< LAME psy model FIR order#define AAC_BLOCK_SIZE_LONG 1024    ///< long block size#define AAC_BLOCK_SIZE_SHORT 128    ///< short block size#define AAC_NUM_BLOCKS_SHORT 8      ///< number of blocks in a short sequence#define PSY_LAME_NUM_SUBBLOCKS 3    ///< Number of sub-blocks in each short block /** * @} */ /** * information for single band used by 3GPP TS26.403-inspired psychoacoustic model */typedef struct AacPsyBand{    float energy;       ///< band energy    float thr;          ///< energy threshold    float thr_quiet;    ///< threshold in quiet    float nz_lines;     ///< number of non-zero spectral lines    float active_lines; ///< number of active spectral lines    float pe;           ///< perceptual entropy    float pe_const;     ///< constant part of the PE calculation    float norm_fac;     ///< normalization factor for linearization    int   avoid_holes;  ///< hole avoidance flag}AacPsyBand; /** * single/pair channel context for psychoacoustic model */typedef struct AacPsyChannel{    AacPsyBand band[128];               ///< bands information    AacPsyBand 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    /* LAME psy model specific members */    float attack_threshold;              ///< attack threshold for this channel    float prev_energy_subshort[AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS];    int   prev_attack;                   ///< attack value for the last short block in the previous sequence}AacPsyChannel; /** * psychoacoustic model frame type-dependent coefficients */typedef struct AacPsyCoeffs{    float ath;           ///< absolute threshold of hearing per bands    float barks;         ///< Bark value for each spectral band in long frame    float spread_low[2]; ///< spreading factor for low-to-high threshold spreading in long frame    float spread_hi [2]; ///< spreading factor for high-to-low threshold spreading in long frame    float min_snr;       ///< minimal SNR}AacPsyCoeffs; /** * 3GPP TS26.403-inspired psychoacoustic model specific data */typedef struct AacPsyContext{    int chan_bitrate;     ///< bitrate per channel    int frame_bits;       ///< average bits per frame    int fill_level;       ///< bit reservoir fill level    struct {        float min;        ///< minimum allowed PE for bit factor calculation        float max;        ///< maximum allowed PE for bit factor calculation        float previous;   ///< allowed PE of the previous frame        float correction; ///< PE correction factor    } pe;    AacPsyCoeffs psy_coef[2][64];    AacPsyChannel *ch;    float global_quality; ///< normalized global quality taken from avctx}AacPsyContext; /** * LAME psy model preset struct */typedef struct PsyLamePreset {    int   quality;  ///< Quality to map the rest of the vaules to.     /* This is overloaded to be both kbps per channel in ABR mode, and      * requested quality in constant quality mode.      */    float st_lrm;   ///< short threshold for L, R, and M channels} PsyLamePreset; /** * LAME psy model preset table for ABR */static const PsyLamePreset psy_abr_map[] = {/* TODO: Tuning. These were taken from LAME. *//* kbps/ch st_lrm   */    {  8,  6.60},    { 16,  6.60},    { 24,  6.60},    { 32,  6.60},    { 40,  6.60},    { 48,  6.60},    { 56,  6.60},    { 64,  6.40},    { 80,  6.00},    { 96,  5.60},    {112,  5.20},    {128,  5.20},    {160,  5.20}}; /*** LAME psy model preset table for constant quality*/static const PsyLamePreset psy_vbr_map[] = {/* vbr_q  st_lrm    */    { 0,  4.20},    { 1,  4.20},    { 2,  4.20},    { 3,  4.20},    { 4,  4.20},    { 5,  4.20},    { 6,  4.20},    { 7,  4.20},    { 8,  4.20},    { 9,  4.20},    {10,  4.20}}; /** * LAME psy model FIR coefficient table */static const float psy_fir_coeffs[] = {    -8.65163e-18 * 2, -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2,    -3.36639e-17 * 2, -0.0438162 * 2,  -1.54175e-17 * 2, 0.0931738 * 2,    -5.52212e-17 * 2, -0.313819 * 2}; #if ARCH_MIPS#   include "mips/aacpsy_mips.h"#endif /* ARCH_MIPS */ /** * Calculate the ABR attack threshold from the above LAME psymodel table. */static float lame_calc_attack_threshold(int bitrate){    /* Assume max bitrate to start with */    int lower_range = 12, upper_range = 12;    int lower_range_kbps = psy_abr_map[12].quality;    int upper_range_kbps = psy_abr_map[12].quality;    int i;     /* Determine which bitrates the value specified falls between.     * If the loop ends without breaking our above assumption of 320kbps was correct.     */    for (i = 1; i < 13; i++) {        if (FFMAX(bitrate, psy_abr_map[i].quality) != bitrate) {            upper_range = i;            upper_range_kbps = psy_abr_map[i    ].quality;            lower_range = i - 1;            lower_range_kbps = psy_abr_map[i - 1].quality;            break; /* Upper range found */        }    }     /* Determine which range the value specified is closer to */    if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps))        return psy_abr_map[lower_range].st_lrm;    return psy_abr_map[upper_range].st_lrm;} /** * LAME psy model specific initialization */static av_cold void lame_window_init(AacPsyContext *ctx, AVCodecContext *avctx){    int i, j;     for (i = 0; i < avctx->channels; i++) {        AacPsyChannel *pch = &ctx->ch[i];         if (avctx->flags & AV_CODEC_FLAG_QSCALE)            pch->attack_threshold = psy_vbr_map[avctx->global_quality / FF_QP2LAMBDA].st_lrm;        else            pch->attack_threshold = lame_calc_attack_threshold(avctx->bit_rate / avctx->channels / 1000);         for (j = 0; j < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; j++)            pch->prev_energy_subshort[j] = 10.0f;    }} /** * Calculate Bark value for given line. */static av_cold float calc_bark(float f){    return 13.3f * atanf(0.00076f * f) + 3.5f * atanf((f / 7500.0f) * (f / 7500.0f));} #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;    return    3.64 * pow(f, -0.8)            - 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;} static av_cold int psy_3gpp_init(FFPsyContext *ctx) {    AacPsyContext *pctx;    float bark;    int i, j, g, start;    float prev, minscale, minath, minsnr, pe_min;    int chan_bitrate = ctx->avctx->bit_rate / ((ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : ctx->avctx->channels);     const int bandwidth    = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx);    const float num_bark   = calc_bark((float)bandwidth);     ctx->model_priv_data = av_mallocz(sizeof(AacPsyContext));    if (!ctx->model_priv_data)        return AVERROR(ENOMEM);    pctx = ctx->model_priv_data;    pctx->global_quality = (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120) * 0.01f;     if (ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) {        /* Use the target average bitrate to compute spread parameters */        chan_bitrate = (int)(chan_bitrate / 120.0 * (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120));    }     pctx->chan_bitrate = chan_bitrate;    pctx->frame_bits   = FFMIN(2560, chan_bitrate * AAC_BLOCK_SIZE_LONG / ctx->avctx->sample_rate);    pctx->pe.min       =  8.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f);    pctx->pe.max       = 12.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f);    ctx->bitres.size   = 6144 - pctx->frame_bits;    ctx->bitres.size  -= ctx->bitres.size % 8;    pctx->fill_level   = ctx->bitres.size;    minath = ath(3410 - 0.733 * ATH_ADD, ATH_ADD);    for (j = 0; j < 2; j++) {        AacPsyCoeffs *coeffs = pctx->psy_coef[j];        const uint8_t *band_sizes = ctx->bands[j];        float line_to_frequency = ctx->avctx->sample_rate / (j ? 256.f : 2048.0f);        float avg_chan_bits = chan_bitrate * (j ? 128.0f : 1024.0f) / ctx->avctx->sample_rate;        /* reference encoder uses 2.4% here instead of 60% like the spec says */        float bark_pe = 0.024f * PSY_3GPP_BITS_TO_PE(avg_chan_bits) / num_bark;        float en_spread_low = j ? PSY_3GPP_EN_SPREAD_LOW_S : PSY_3GPP_EN_SPREAD_LOW_L;        /* High energy spreading for long blocks <= 22kbps/channel and short blocks are the same. */        float en_spread_hi  = (j || (chan_bitrate <= 22.0f)) ? PSY_3GPP_EN_SPREAD_HI_S : PSY_3GPP_EN_SPREAD_HI_L1;         i = 0;        prev = 0.0;        for (g = 0; g < ctx->num_bands[j]; g++) {            i += band_sizes[g];            bark = calc_bark((i-1) * line_to_frequency);            coeffs[g].barks = (bark + prev) / 2.0;            prev = bark;        }        for (g = 0; g < ctx->num_bands[j] - 1; g++) {            AacPsyCoeffs *coeff = &coeffs[g];            float bark_width = coeffs[g+1].barks - coeffs->barks;            coeff->spread_low[0] = ff_exp10(-bark_width * PSY_3GPP_THR_SPREAD_LOW);            coeff->spread_hi [0] = ff_exp10(-bark_width * PSY_3GPP_THR_SPREAD_HI);            coeff->spread_low[1] = ff_exp10(-bark_width * en_spread_low);            coeff->spread_hi [1] = ff_exp10(-bark_width * en_spread_hi);            pe_min = bark_pe * bark_width;            minsnr = exp2(pe_min / band_sizes[g]) - 1.5f;            coeff->min_snr = av_clipf(1.0f / minsnr, PSY_SNR_25DB, PSY_SNR_1DB);        }        start = 0;        for (g = 0; g < ctx->num_bands[j]; g++) {            minscale = ath(start * line_to_frequency, ATH_ADD);            for (i = 1; i < band_sizes[g]; i++)                minscale = FFMIN(minscale, ath((start + i) * line_to_frequency, ATH_ADD));            coeffs[g].ath = minscale - minath;            start += band_sizes[g];        }    }     pctx->ch = av_mallocz_array(ctx->avctx->channels, sizeof(AacPsyChannel));    if (!pctx->ch) {        av_freep(&ctx->model_priv_data);        return AVERROR(ENOMEM);    }     lame_window_init(pctx, ctx->avctx);     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 av_unused FFPsyWindowInfo psy_3gpp_window(FFPsyContext *ctx,                                                 const int16_t *audio,                                                 const int16_t *la,                                                 int channel, int prev_type){    int i, j;    int br               = ((AacPsyContext*)ctx->model_priv_data)->chan_bitrate;    int attack_ratio     = br <= 16000 ? 18 : 10;    AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;    AacPsyChannel *pch  = &pctx->ch[channel];    uint8_t grouping     = 0;    int next_type        = pch->next_window_seq;    FFPsyWindowInfo wi  = { { 0 } };     if (la) {        float s[8], v;        int switch_to_eight = 0;        float sum = 0.0, sum2 = 0.0;        int attack_n = 0;        int stay_short = 0;        for (i = 0; i < 8; i++) {            for (j = 0; j < 128; j++) {                v = iir_filter(la[i*128+j], pch->iir_state);                sum += v*v;            }            s[i]  = sum;            sum2 += sum;        }        for (i = 0; i < 8; i++) {            if (s[i] > pch->win_energy * attack_ratio) {                attack_n        = i + 1;                switch_to_eight = 1;                break;            }        }        pch->win_energy = pch->win_energy*7/8 + sum2/64;         wi.window_type[1] = prev_type;        switch (prev_type) {        case ONLY_LONG_SEQUENCE:            wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE;            next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE;            break;        case LONG_START_SEQUENCE:            wi.window_type[0] = EIGHT_SHORT_SEQUENCE;            grouping = pch->next_grouping;            next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;            break;        case LONG_STOP_SEQUENCE:            wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE;            next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE;            break;        case EIGHT_SHORT_SEQUENCE:            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;            break;        }         pch->next_grouping = window_grouping[attack_n];        pch->next_window_seq = next_type;    } else {        for (i = 0; i < 3; i++)            wi.window_type[i] = prev_type;        grouping = (prev_type == EIGHT_SHORT_SEQUENCE) ? window_grouping[0] : 0;    }     wi.window_shape   = 1;    if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) {        wi.num_windows = 1;        wi.grouping[0] = 1;    } else {        int lastgrp = 0;        wi.num_windows = 8;        for (i = 0; i < 8; i++) {            if (!((grouping >> i) & 1))                lastgrp = i;            wi.grouping[lastgrp]++;        }    }     return wi;} /* 5.6.1.2 "Calculation of Bit Demand" */static int calc_bit_demand(AacPsyContext *ctx, float pe, int bits, int size,                           int short_window){    const float bitsave_slope  = short_window ? PSY_3GPP_SAVE_SLOPE_S  : PSY_3GPP_SAVE_SLOPE_L;    const float bitsave_add    = short_window ? PSY_3GPP_SAVE_ADD_S    : PSY_3GPP_SAVE_ADD_L;    const float bitspend_slope = short_window ? PSY_3GPP_SPEND_SLOPE_S : PSY_3GPP_SPEND_SLOPE_L;    const float bitspend_add   = short_window ? PSY_3GPP_SPEND_ADD_S   : PSY_3GPP_SPEND_ADD_L;    const float clip_low       = short_window ? PSY_3GPP_CLIP_LO_S     : PSY_3GPP_CLIP_LO_L;    const float clip_high      = short_window ? PSY_3GPP_CLIP_HI_S     : PSY_3GPP_CLIP_HI_L;    float clipped_pe, bit_save, bit_spend, bit_factor, fill_level, forgetful_min_pe;

Lines 1–500 of 1025.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t