Source file: /~heha/hsn/puh.zip/presets.cpp

/*  Apply presets
 *	Copyright 2002-2008 Gabriel Bouvigne
 *	Copyright 2007-2012 Robert Hegemann
 */

#include "lame.h"
#include "machine.h"
#include "set_get.h"
#include "encoder.h"
#include "util.h"
#include "lame_global_flags.h"

#define SET_OPTION(opt, val, def) if (enforce) lame_set_##opt(val); \
    else if (!(fabs(float(lame_get_##opt() - def)) > 0)) lame_set_##opt(val);

#define SET__OPTION(opt, val, def) if (enforce) lame_set_##opt(val); \
    else if (!(fabs(lame_get_##opt() - def) > 0)) lame_set_##opt(val);

#undef Min
#undef Max

static inline int min_int(int a, int b) {return a < b ? a : b;}
static inline int max_int(int a, int b) {return a > b ? a : b;}

struct vbr_presets_t{
  int     vbr_q;
  int     quant_comp;
  int     quant_comp_s;
  int     expY;
  FLOAT   st_lrm;          /*short threshold */
  FLOAT   st_s;
  FLOAT   masking_adj;
  FLOAT   masking_adj_short;
  FLOAT   ath_lower;
  FLOAT   ath_curve;
  FLOAT   ath_sensitivity;
  FLOAT   interch;
  int     safejoint;
  int     sfb21mod;
  FLOAT   msfix;
  FLOAT   minval;
  FLOAT   ath_fixpoint;
};

    /* *INDENT-OFF* */
    
    /* Switch mappings for VBR mode VBR_RH */
static const vbr_presets_t vbr_old_switch_map[] = {
/* q  l  s expY st_lrm st_s  mask adj_l  adj_s  ath_lower  ath_curve  ath_sens  interChR  safejoint sfb21mod  msfix */
  {0, 9, 9, 0,   5.20, 125.0,  -4.2, -6.3,       4.8,       1,          0,   0,              2,      21,  0.97, 5, 100},
  {1, 9, 9, 0,   5.30, 125.0,  -3.6, -5.6,       4.5,       1.5,        0,   0,              2,      21,  1.35, 5, 100},
  {2, 9, 9, 0,   5.60, 125.0,  -2.2, -3.5,       2.8,       2,          0,   0,              2,      21,  1.49, 5, 100},
  {3, 9, 9, 1,   5.80, 130.0,  -1.8, -2.8,       2.6,       3,         -4,   0,              2,      20,  1.64, 5, 100},
  {4, 9, 9, 1,   6.00, 135.0,  -0.7, -1.1,       1.1,       3.5,       -8,   0,              2,       0,  1.79, 5, 100},
  {5, 9, 9, 1,   6.40, 140.0,   0.5,  0.4,      -7.5,       4,        -12,   0.0002,         0,       0,  1.95, 5, 100},
  {6, 9, 9, 1,   6.60, 145.0,  0.67,  0.65,    -14.7,       6.5,      -19,   0.0004,         0,       0,  2.30, 5, 100},
  {7, 9, 9, 1,   6.60, 145.0,   0.8,  0.75,    -19.7,       8,        -22,   0.0006,         0,       0,  2.70, 5, 100},
  {8, 9, 9, 1,   6.60, 145.0,   1.2,  1.15,    -27.5,      10,        -23,   0.0007,         0,       0,  0,    5, 100},
  {9, 9, 9, 1,   6.60, 145.0,   1.6,  1.6,     -36,        11,        -25,   0.0008,         0,       0,  0,    5, 100},
  {10,9, 9, 1,   6.60, 145.0,   2.0,  2.0,     -36,        12,        -25,   0.0008,         0,       0,  0,    5, 100}
};
    
static const vbr_presets_t vbr_mt_psy_switch_map[] = {
    /*vbr_q  qcomp_l  qcomp_s  expY  st_lrm   st_s  mask adj_l  adj_s  ath_lower  ath_curve  ath_sens  ---  safejoint sfb21mod  msfix */
  {0, 9, 9, 0,   4.20,  25.0,  -6.8, -6.8,       7.1,       1,          0,   0,         2,      31,  1.000,  5, 100},
  {1, 9, 9, 0,   4.20,  25.0,  -4.8, -4.8,       5.4,       1.4,       -1,   0,         2,      27,  1.122,  5,  98},
  {2, 9, 9, 0,   4.20,  25.0,  -2.6, -2.6,       3.7,       2.0,       -3,   0,         2,      23,  1.288,  5,  97},
  {3, 9, 9, 1,   4.20,  25.0,  -1.6, -1.6,       2.0,       2.0,       -5,   0,         2,      18,  1.479,  5,  96},
  {4, 9, 9, 1,   4.20,  25.0,  -0.0, -0.0,       0.0,       2.0,       -8,   0,         2,      12,  1.698,  5,  95},
  {5, 9, 9, 1,   4.20,  25.0,   1.3,  1.3,      -6,         3.5,      -11,   0,         2,       8,  1.950,  5,  94.2},
#if 0
  {6, 9, 9, 1,   4.50, 100.0,   1.5,  1.5,     -24.0,       6.0,      -14,   0,         2,       4,  2.239,  3,  93.9},
  {7, 9, 9, 1,   4.80, 200.0,   1.7,  1.7,     -28.0,       9.0,      -20,   0,         2,       0,  2.570,  1,  93.6},
#else
  {6, 9, 9, 1,   4.50, 100.0,   2.2,  2.3,     -12.0,       6.0,      -14,   0,         2,       4,  2.239,  3,  93.9},
  {7, 9, 9, 1,   4.80, 200.0,   2.7,  2.7,     -18.0,       9.0,      -17,   0,         2,       0,  2.570,  1,  93.6},
#endif
  {8, 9, 9, 1,   5.30, 300.0,   2.8,  2.8,     -21.0,      10.0,      -23,   0.0002,    0,       0,  2.951,  0,  93.3},
  {9, 9, 9, 1,   6.60, 300.0,   2.8,  2.8,     -23.0,      11.0,      -25,   0.0006,    0,       0,  3.388,  0,  93.3},
  {10,9, 9, 1,  25.00, 300.0,   2.8,  2.8,     -25.0,      12.0,      -27,   0.0025,    0,       0,  3.500,  0,  93.3}
};

static vbr_presets_t const* get_vbr_preset(int v) {
  switch (v) {
    case vbr_mtrh:
    case vbr_mt:
        return &vbr_mt_psy_switch_map[0];
    default:
        return &vbr_old_switch_map[0];
  }
}

#define NOOP(m) (void)p.m
#define LERP(m) (p.m = p.m + x * (q.m - p.m))

void lame_global_flags::apply_vbr_preset(int a,bool enforce) {
  vbr_presets_t const *vbr_preset = get_vbr_preset(lame_get_VBR());
  float   x = VBR_q_frac;
  vbr_presets_t p = vbr_preset[a];
  vbr_presets_t q = vbr_preset[a + 1];
  vbr_presets_t const *set = &p;

  NOOP(vbr_q);
  NOOP(quant_comp);
  NOOP(quant_comp_s);
  NOOP(expY);
  LERP(st_lrm);
  LERP(st_s);
  LERP(masking_adj);
  LERP(masking_adj_short);
  LERP(ath_lower);
  LERP(ath_curve);
  LERP(ath_sensitivity);
  LERP(interch);
  NOOP(safejoint);
  LERP(sfb21mod);
  LERP(msfix);
  LERP(minval);
  LERP(ath_fixpoint);

  lame_set_VBR_q(set->vbr_q);
  SET_OPTION(quant_comp, set->quant_comp, -1);
  SET_OPTION(quant_comp_short, set->quant_comp_s, -1);
  if (set->expY) lame_set_experimentalY(set->expY);
  SET_OPTION(short_threshold_lrm, set->st_lrm, -1);
  SET_OPTION(short_threshold_s, set->st_s, -1);
  SET_OPTION(maskingadjust, set->masking_adj, 0);
  SET_OPTION(maskingadjust_short, set->masking_adj_short, 0);
  if (lame_get_VBR() == vbr_mt || lame_get_VBR() == vbr_mtrh) {
    lame_set_ATHtype(5);
  }
  SET_OPTION(ATHlower, set->ath_lower, 0);
  SET_OPTION(ATHcurve, set->ath_curve, -1);
  SET_OPTION(athaa_sensitivity, set->ath_sensitivity, 0);
  if (set->interch > 0) {
    SET_OPTION(interChRatio, set->interch, -1);
  }

    /* parameters for which there is no proper set/get interface */
  if (set->safejoint > 0) {
    lame_set_exp_nspsytune(lame_get_exp_nspsytune() | 2);
  }
  if (set->sfb21mod > 0) {
    int const nsp = lame_get_exp_nspsytune();
    int const val = (nsp >> 20) & 63;
    if (!val) {
      int const sf21mod = (set->sfb21mod << 20) | nsp;
      lame_set_exp_nspsytune(sf21mod);
    }
  }
  SET__OPTION(msfix, set->msfix, -1);

  if (!enforce) {
    VBR_q = a;
    VBR_q_frac = x;
  }
  internal_flags->cfg.minval = set->minval;
  {   /* take care of gain adjustments */
    double const x = fabs(scale);
    double const y = (x > 0.f) ? (10.f * log10(x)) : 0.f;
    internal_flags->cfg.ATHfixpoint = set->ath_fixpoint - y;
  }
}

int lame_global_flags::apply_abr_preset(int p, bool enforce) {
    typedef struct {
        int     abr_kbps;
        int     quant_comp;
        int     quant_comp_s;
        int     safejoint;
        FLOAT   nsmsfix;
        FLOAT   st_lrm;      /*short threshold */
        FLOAT   st_s;
        FLOAT   scale;
        FLOAT   masking_adj;
        FLOAT   ath_lower;
        FLOAT   ath_curve;
        FLOAT   interch;
        int     sfscale;
    } abr_presets_t;


    /* *INDENT-OFF* */

    /* 
     *  Switch mappings for ABR mode
     */
    const abr_presets_t abr_switch_map[] = {        
    /* kbps  quant q_s safejoint nsmsfix st_lrm  st_s  scale   msk ath_lwr ath_curve  interch , sfscale */
      {  8,     9,  9,        0,      0,  6.60,  145,  0.95,    0,  -30.0,     11,    0.0012,        1}, /*   8, impossible to use in stereo */
      { 16,     9,  9,        0,      0,  6.60,  145,  0.95,    0,  -25.0,     11,    0.0010,        1}, /*  16 */
      { 24,     9,  9,        0,      0,  6.60,  145,  0.95,    0,  -20.0,     11,    0.0010,        1}, /*  24 */
      { 32,     9,  9,        0,      0,  6.60,  145,  0.95,    0,  -15.0,     11,    0.0010,        1}, /*  32 */
      { 40,     9,  9,        0,      0,  6.60,  145,  0.95,    0,  -10.0,     11,    0.0009,        1}, /*  40 */
      { 48,     9,  9,        0,      0,  6.60,  145,  0.95,    0,  -10.0,     11,    0.0009,        1}, /*  48 */
      { 56,     9,  9,        0,      0,  6.60,  145,  0.95,    0,   -6.0,     11,    0.0008,        1}, /*  56 */
      { 64,     9,  9,        0,      0,  6.60,  145,  0.95,    0,   -2.0,     11,    0.0008,        1}, /*  64 */
      { 80,     9,  9,        0,      0,  6.60,  145,  0.95,    0,     .0,      8,    0.0007,        1}, /*  80 */
      { 96,     9,  9,        0,   2.50,  6.60,  145,  0.95,    0,    1.0,      5.5,  0.0006,        1}, /*  96 */
      {112,     9,  9,        0,   2.25,  6.60,  145,  0.95,    0,    2.0,      4.5,  0.0005,        1}, /* 112 */
      {128,     9,  9,        0,   1.95,  6.40,  140,  0.95,    0,    3.0,      4,    0.0002,        1}, /* 128 */
      {160,     9,  9,        1,   1.79,  6.00,  135,  0.95,   -2,    5.0,      3.5,  0,             1}, /* 160 */
      {192,     9,  9,        1,   1.49,  5.60,  125,  0.97,   -4,    7.0,      3,    0,             0}, /* 192 */
      {224,     9,  9,        1,   1.25,  5.20,  125,  0.98,   -6,    9.0,      2,    0,             0}, /* 224 */
      {256,     9,  9,        1,   0.97,  5.20,  125,  1.00,   -8,   10.0,      1,    0,             0}, /* 256 */
      {320,     9,  9,        1,   0.90,  5.20,  125,  1.00,  -10,   12.0,      0,    0,             0}  /* 320 */
    };

    /* *INDENT-ON* */

    /* Variables for the ABR stuff */
    int     r;
    int     actual_bitrate = p;

    r = nearestBitrateFullIndex(p);
    
    (void) lame_set_VBR(vbr_abr);
    (void) lame_set_VBR_mean_bitrate_kbps((actual_bitrate));
    (void) lame_set_VBR_mean_bitrate_kbps(min_int(lame_get_VBR_mean_bitrate_kbps(), 320));
    (void) lame_set_VBR_mean_bitrate_kbps(max_int(lame_get_VBR_mean_bitrate_kbps(), 8));
    (void) lame_set_brate(lame_get_VBR_mean_bitrate_kbps());


    /* parameters for which there is no proper set/get interface */
    if (abr_switch_map[r].safejoint > 0)
        (void) lame_set_exp_nspsytune(lame_get_exp_nspsytune() | 2); /* safejoint */

    if (abr_switch_map[r].sfscale > 0)
        (void) lame_set_sfscale(1);


    SET_OPTION(quant_comp, abr_switch_map[r].quant_comp, -1);
    SET_OPTION(quant_comp_short, abr_switch_map[r].quant_comp_s, -1);

    SET__OPTION(msfix, abr_switch_map[r].nsmsfix, -1);

    SET_OPTION(short_threshold_lrm, abr_switch_map[r].st_lrm, -1);
    SET_OPTION(short_threshold_s, abr_switch_map[r].st_s, -1);

    /* ABR seems to have big problems with clipping, especially at low bitrates */
    /* so we compensate for that here by using a scale value depending on bitrate */
    set_scale(get_scale() * abr_switch_map[r].scale);

    SET_OPTION(maskingadjust, abr_switch_map[r].masking_adj, 0);
    if (abr_switch_map[r].masking_adj > 0) {
        SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * .9, 0);
    }
    else {
        SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * 1.1, 0);
    }


    SET_OPTION(ATHlower, abr_switch_map[r].ath_lower, 0);
    SET_OPTION(ATHcurve, abr_switch_map[r].ath_curve, -1);

    SET_OPTION(interChRatio, abr_switch_map[r].interch, -1);

    (void) abr_switch_map[r].abr_kbps;

    internal_flags->cfg.minval = 5. * (abr_switch_map[r].abr_kbps / 320.);

    return p;
}



int lame_global_flags::apply_preset(int p, bool enforce) {
    /*translate legacy presets */
  switch (p) {
    case R3MIX: {
      p = V3;
      lame_set_VBR(vbr_mtrh);
    }break;
    case MEDIUM:
    case MEDIUM_FAST: {
      p = V4;
      lame_set_VBR(vbr_mtrh);
    }break;
    case STANDARD:
    case STANDARD_FAST: {
      p = V2;
      lame_set_VBR(vbr_mtrh);
    }break;
    case EXTREME:
    case EXTREME_FAST: {
      p = V0;
      lame_set_VBR(vbr_mtrh);
    }break;
    case INSANE: {
      p = 320;
      preset = p;
      apply_abr_preset(p, enforce);
      lame_set_VBR(vbr_off);
      return p;
    }
  }
  preset = p;
  {
    switch (p) {
        case V9: apply_vbr_preset(9, enforce); return p;
        case V8: apply_vbr_preset(8, enforce); return p;
        case V7: apply_vbr_preset(7, enforce); return p;
        case V6: apply_vbr_preset(6, enforce); return p;
        case V5: apply_vbr_preset(5, enforce); return p;
        case V4: apply_vbr_preset(4, enforce); return p;
        case V3: apply_vbr_preset(3, enforce); return p;
        case V2: apply_vbr_preset(2, enforce); return p;
        case V1: apply_vbr_preset(1, enforce); return p;
        case V0: apply_vbr_preset(0, enforce); return p;
    }
  }
  if (8 <= p && p <= 320) {
    return apply_abr_preset(p, enforce);
  }

  preset = 0;    /*no corresponding preset found */
  return p;
}
Detected encoding: ASCII (7 bit)2