123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- /*
- * presets.c -- Apply presets
- *
- * Copyright (c) 2002-2008 Gabriel Bouvigne
- * Copyright (c) 2007-2012 Robert Hegemann
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
- #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) \
- (void) lame_set_##opt(gfp, val); \
- else if (!(fabs((float)(lame_get_##opt(gfp)) - (float)(def)) > 0)) \
- (void) lame_set_##opt(gfp, val);
- #define SET__OPTION(opt, val, def) if (enforce) \
- lame_set_##opt(gfp, val); \
- else if (!(fabs((float)(lame_get_##opt(gfp)) - (float)(def)) > 0)) \
- lame_set_##opt(gfp, val);
- #undef Min
- #undef Max
- static inline int
- min_int(int a, int b)
- {
- if (a < b) {
- return a;
- }
- return b;
- }
- static inline int
- max_int(int a, int b)
- {
- if (a > b) {
- return a;
- }
- return b;
- }
- typedef struct {
- 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;
- } vbr_presets_t;
- /* *INDENT-OFF* */
-
- /* Switch mappings for VBR mode VBR_RH */
- static const vbr_presets_t vbr_old_switch_map[] = {
- /*vbr_q qcomp_l qcomp_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}
- };
- /* *INDENT-ON* */
- 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))
- static void
- apply_vbr_preset(lame_global_flags * gfp, int a, int enforce)
- {
- vbr_presets_t const *vbr_preset = get_vbr_preset(lame_get_VBR(gfp));
- float x = gfp->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);
- (void) lame_set_VBR_q(gfp, set->vbr_q);
- SET_OPTION(quant_comp, set->quant_comp, -1);
- SET_OPTION(quant_comp_short, set->quant_comp_s, -1);
- if (set->expY) {
- (void) lame_set_experimentalY(gfp, 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(gfp) == vbr_mt || lame_get_VBR(gfp) == vbr_mtrh) {
- lame_set_ATHtype(gfp, 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) {
- (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2);
- }
- if (set->sfb21mod > 0) {
- int const nsp = lame_get_exp_nspsytune(gfp);
- int const val = (nsp >> 20) & 63;
- if (val == 0) {
- int const sf21mod = (set->sfb21mod << 20) | nsp;
- (void) lame_set_exp_nspsytune(gfp, sf21mod);
- }
- }
- SET__OPTION(msfix, set->msfix, -1);
- if (enforce == 0) {
- gfp->VBR_q = a;
- gfp->VBR_q_frac = x;
- }
- gfp->internal_flags->cfg.minval = set->minval;
- { /* take care of gain adjustments */
- double const x = fabs(gfp->scale);
- double const y = (x > 0.f) ? (10.f * log10(x)) : 0.f;
- gfp->internal_flags->cfg.ATHfixpoint = set->ath_fixpoint - y;
- }
- }
- static int
- apply_abr_preset(lame_global_flags * gfp, int preset, int 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 = preset;
- r = nearestBitrateFullIndex(preset);
-
- (void) lame_set_VBR(gfp, vbr_abr);
- (void) lame_set_VBR_mean_bitrate_kbps(gfp, (actual_bitrate));
- (void) lame_set_VBR_mean_bitrate_kbps(gfp, min_int(lame_get_VBR_mean_bitrate_kbps(gfp), 320));
- (void) lame_set_VBR_mean_bitrate_kbps(gfp, max_int(lame_get_VBR_mean_bitrate_kbps(gfp), 8));
- (void) lame_set_brate(gfp, lame_get_VBR_mean_bitrate_kbps(gfp));
- /* parameters for which there is no proper set/get interface */
- if (abr_switch_map[r].safejoint > 0)
- (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2); /* safejoint */
- if (abr_switch_map[r].sfscale > 0)
- (void) lame_set_sfscale(gfp, 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 */
- lame_set_scale(gfp, lame_get_scale(gfp) * 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;
- gfp->internal_flags->cfg.minval = 5. * (abr_switch_map[r].abr_kbps / 320.);
- return preset;
- }
- int
- apply_preset(lame_global_flags * gfp, int preset, int enforce)
- {
- /*translate legacy presets */
- switch (preset) {
- case R3MIX:
- {
- preset = V3;
- (void) lame_set_VBR(gfp, vbr_mtrh);
- break;
- }
- case MEDIUM:
- case MEDIUM_FAST:
- {
- preset = V4;
- (void) lame_set_VBR(gfp, vbr_mtrh);
- break;
- }
- case STANDARD:
- case STANDARD_FAST:
- {
- preset = V2;
- (void) lame_set_VBR(gfp, vbr_mtrh);
- break;
- }
- case EXTREME:
- case EXTREME_FAST:
- {
- preset = V0;
- (void) lame_set_VBR(gfp, vbr_mtrh);
- break;
- }
- case INSANE:
- {
- preset = 320;
- gfp->preset = preset;
- (void) apply_abr_preset(gfp, preset, enforce);
- lame_set_VBR(gfp, vbr_off);
- return preset;
- }
- }
- gfp->preset = preset;
- {
- switch (preset) {
- case V9:
- apply_vbr_preset(gfp, 9, enforce);
- return preset;
- case V8:
- apply_vbr_preset(gfp, 8, enforce);
- return preset;
- case V7:
- apply_vbr_preset(gfp, 7, enforce);
- return preset;
- case V6:
- apply_vbr_preset(gfp, 6, enforce);
- return preset;
- case V5:
- apply_vbr_preset(gfp, 5, enforce);
- return preset;
- case V4:
- apply_vbr_preset(gfp, 4, enforce);
- return preset;
- case V3:
- apply_vbr_preset(gfp, 3, enforce);
- return preset;
- case V2:
- apply_vbr_preset(gfp, 2, enforce);
- return preset;
- case V1:
- apply_vbr_preset(gfp, 1, enforce);
- return preset;
- case V0:
- apply_vbr_preset(gfp, 0, enforce);
- return preset;
- default:
- break;
- }
- }
- if (8 <= preset && preset <= 320) {
- return apply_abr_preset(gfp, preset, enforce);
- }
- gfp->preset = 0; /*no corresponding preset found */
- return preset;
- }
|