1/* 2 * presets.c -- Apply presets 3 * 4 * Copyright (c) 2002-2008 Gabriel Bouvigne 5 * Copyright (c) 2007-2012 Robert Hegemann 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Library General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Library General Public License for more details. 16 * 17 * You should have received a copy of the GNU Library General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 20 */ 21 22 23#ifdef HAVE_CONFIG_H 24# include <config.h> 25#endif 26 27#include "lame.h" 28#include "machine.h" 29#include "set_get.h" 30#include "encoder.h" 31#include "util.h" 32#include "lame_global_flags.h" 33 34#define SET_OPTION(opt, val, def) if (enforce) \ 35 (void) lame_set_##opt(gfp, val); \ 36 else if (!(fabs(lame_get_##opt(gfp) - def) > 0)) \ 37 (void) lame_set_##opt(gfp, val); 38 39#define SET__OPTION(opt, val, def) if (enforce) \ 40 lame_set_##opt(gfp, val); \ 41 else if (!(fabs(lame_get_##opt(gfp) - def) > 0)) \ 42 lame_set_##opt(gfp, val); 43 44#undef Min 45#undef Max 46 47static inline int 48min_int(int a, int b) 49{ 50 if (a < b) { 51 return a; 52 } 53 return b; 54} 55 56static inline int 57max_int(int a, int b) 58{ 59 if (a > b) { 60 return a; 61 } 62 return b; 63} 64 65 66 67typedef struct { 68 int vbr_q; 69 int quant_comp; 70 int quant_comp_s; 71 int expY; 72 FLOAT st_lrm; /*short threshold */ 73 FLOAT st_s; 74 FLOAT masking_adj; 75 FLOAT masking_adj_short; 76 FLOAT ath_lower; 77 FLOAT ath_curve; 78 FLOAT ath_sensitivity; 79 FLOAT interch; 80 int safejoint; 81 int sfb21mod; 82 FLOAT msfix; 83 FLOAT minval; 84 FLOAT ath_fixpoint; 85} vbr_presets_t; 86 87 /* *INDENT-OFF* */ 88 89 /* Switch mappings for VBR mode VBR_RH */ 90 static const vbr_presets_t vbr_old_switch_map[] = { 91 /*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 */ 92 {0, 9, 9, 0, 5.20, 125.0, -4.2, -6.3, 4.8, 1, 0, 0, 2, 21, 0.97, 5, 100}, 93 {1, 9, 9, 0, 5.30, 125.0, -3.6, -5.6, 4.5, 1.5, 0, 0, 2, 21, 1.35, 5, 100}, 94 {2, 9, 9, 0, 5.60, 125.0, -2.2, -3.5, 2.8, 2, 0, 0, 2, 21, 1.49, 5, 100}, 95 {3, 9, 9, 1, 5.80, 130.0, -1.8, -2.8, 2.6, 3, -4, 0, 2, 20, 1.64, 5, 100}, 96 {4, 9, 9, 1, 6.00, 135.0, -0.7, -1.1, 1.1, 3.5, -8, 0, 2, 0, 1.79, 5, 100}, 97 {5, 9, 9, 1, 6.40, 140.0, 0.5, 0.4, -7.5, 4, -12, 0.0002, 0, 0, 1.95, 5, 100}, 98 {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}, 99 {7, 9, 9, 1, 6.60, 145.0, 0.8, 0.75, -19.7, 8, -22, 0.0006, 0, 0, 2.70, 5, 100}, 100 {8, 9, 9, 1, 6.60, 145.0, 1.2, 1.15, -27.5, 10, -23, 0.0007, 0, 0, 0, 5, 100}, 101 {9, 9, 9, 1, 6.60, 145.0, 1.6, 1.6, -36, 11, -25, 0.0008, 0, 0, 0, 5, 100}, 102 {10, 9, 9, 1, 6.60, 145.0, 2.0, 2.0, -36, 12, -25, 0.0008, 0, 0, 0, 5, 100} 103 }; 104 105 static const vbr_presets_t vbr_mt_psy_switch_map[] = { 106 /*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 */ 107 {0, 9, 9, 0, 4.20, 25.0, -6.8, -6.8, 7.1, 1, 0, 0, 2, 31, 1.000, 5, 100}, 108 {1, 9, 9, 0, 4.20, 25.0, -4.8, -4.8, 5.4, 1.4, -1, 0, 2, 27, 1.122, 5, 98}, 109 {2, 9, 9, 0, 4.20, 25.0, -2.6, -2.6, 3.7, 2.0, -3, 0, 2, 23, 1.288, 5, 97}, 110 {3, 9, 9, 1, 4.20, 25.0, -1.6, -1.6, 2.0, 2.0, -5, 0, 2, 18, 1.479, 5, 96}, 111 {4, 9, 9, 1, 4.20, 25.0, -0.0, -0.0, 0.0, 2.0, -8, 0, 2, 12, 1.698, 5, 95}, 112 {5, 9, 9, 1, 4.20, 25.0, 1.3, 1.3, -6, 3.5, -11, 0, 2, 8, 1.950, 5, 94.2}, 113#if 0 114 {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}, 115 {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}, 116#else 117 {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}, 118 {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}, 119#endif 120 {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}, 121 {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}, 122 {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} 123 }; 124 125 /* *INDENT-ON* */ 126 127static vbr_presets_t const* 128get_vbr_preset(int v) 129{ 130 switch (v) { 131 case vbr_mtrh: 132 case vbr_mt: 133 return &vbr_mt_psy_switch_map[0]; 134 default: 135 return &vbr_old_switch_map[0]; 136 } 137} 138 139#define NOOP(m) (void)p.m 140#define LERP(m) (p.m = p.m + x * (q.m - p.m)) 141 142static void 143apply_vbr_preset(lame_global_flags * gfp, int a, int enforce) 144{ 145 vbr_presets_t const *vbr_preset = get_vbr_preset(lame_get_VBR(gfp)); 146 float x = gfp->VBR_q_frac; 147 vbr_presets_t p = vbr_preset[a]; 148 vbr_presets_t q = vbr_preset[a + 1]; 149 vbr_presets_t const *set = &p; 150 151 NOOP(vbr_q); 152 NOOP(quant_comp); 153 NOOP(quant_comp_s); 154 NOOP(expY); 155 LERP(st_lrm); 156 LERP(st_s); 157 LERP(masking_adj); 158 LERP(masking_adj_short); 159 LERP(ath_lower); 160 LERP(ath_curve); 161 LERP(ath_sensitivity); 162 LERP(interch); 163 NOOP(safejoint); 164 LERP(sfb21mod); 165 LERP(msfix); 166 LERP(minval); 167 LERP(ath_fixpoint); 168 169 (void) lame_set_VBR_q(gfp, set->vbr_q); 170 SET_OPTION(quant_comp, set->quant_comp, -1); 171 SET_OPTION(quant_comp_short, set->quant_comp_s, -1); 172 if (set->expY) { 173 (void) lame_set_experimentalY(gfp, set->expY); 174 } 175 SET_OPTION(short_threshold_lrm, set->st_lrm, -1); 176 SET_OPTION(short_threshold_s, set->st_s, -1); 177 SET_OPTION(maskingadjust, set->masking_adj, 0); 178 SET_OPTION(maskingadjust_short, set->masking_adj_short, 0); 179 if (lame_get_VBR(gfp) == vbr_mt || lame_get_VBR(gfp) == vbr_mtrh) { 180 lame_set_ATHtype(gfp, 5); 181 } 182 SET_OPTION(ATHlower, set->ath_lower, 0); 183 SET_OPTION(ATHcurve, set->ath_curve, -1); 184 SET_OPTION(athaa_sensitivity, set->ath_sensitivity, 0); 185 if (set->interch > 0) { 186 SET_OPTION(interChRatio, set->interch, -1); 187 } 188 189 /* parameters for which there is no proper set/get interface */ 190 if (set->safejoint > 0) { 191 (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2); 192 } 193 if (set->sfb21mod > 0) { 194 int const nsp = lame_get_exp_nspsytune(gfp); 195 int const val = (nsp >> 20) & 63; 196 if (val == 0) { 197 int const sf21mod = (set->sfb21mod << 20) | nsp; 198 (void) lame_set_exp_nspsytune(gfp, sf21mod); 199 } 200 } 201 SET__OPTION(msfix, set->msfix, -1); 202 203 if (enforce == 0) { 204 gfp->VBR_q = a; 205 gfp->VBR_q_frac = x; 206 } 207 gfp->internal_flags->cfg.minval = set->minval; 208 { /* take care of gain adjustments */ 209 double const x = fabs(gfp->scale); 210 double const y = (x > 0.f) ? (10.f * log10(x)) : 0.f; 211 gfp->internal_flags->cfg.ATHfixpoint = set->ath_fixpoint - y; 212 } 213} 214 215static int 216apply_abr_preset(lame_global_flags * gfp, int preset, int enforce) 217{ 218 typedef struct { 219 int abr_kbps; 220 int quant_comp; 221 int quant_comp_s; 222 int safejoint; 223 FLOAT nsmsfix; 224 FLOAT st_lrm; /*short threshold */ 225 FLOAT st_s; 226 FLOAT scale; 227 FLOAT masking_adj; 228 FLOAT ath_lower; 229 FLOAT ath_curve; 230 FLOAT interch; 231 int sfscale; 232 } abr_presets_t; 233 234 235 /* *INDENT-OFF* */ 236 237 /* 238 * Switch mappings for ABR mode 239 */ 240 const abr_presets_t abr_switch_map[] = { 241 /* kbps quant q_s safejoint nsmsfix st_lrm st_s scale msk ath_lwr ath_curve interch , sfscale */ 242 { 8, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -30.0, 11, 0.0012, 1}, /* 8, impossible to use in stereo */ 243 { 16, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -25.0, 11, 0.0010, 1}, /* 16 */ 244 { 24, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -20.0, 11, 0.0010, 1}, /* 24 */ 245 { 32, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -15.0, 11, 0.0010, 1}, /* 32 */ 246 { 40, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -10.0, 11, 0.0009, 1}, /* 40 */ 247 { 48, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -10.0, 11, 0.0009, 1}, /* 48 */ 248 { 56, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -6.0, 11, 0.0008, 1}, /* 56 */ 249 { 64, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -2.0, 11, 0.0008, 1}, /* 64 */ 250 { 80, 9, 9, 0, 0, 6.60, 145, 0.95, 0, .0, 8, 0.0007, 1}, /* 80 */ 251 { 96, 9, 9, 0, 2.50, 6.60, 145, 0.95, 0, 1.0, 5.5, 0.0006, 1}, /* 96 */ 252 {112, 9, 9, 0, 2.25, 6.60, 145, 0.95, 0, 2.0, 4.5, 0.0005, 1}, /* 112 */ 253 {128, 9, 9, 0, 1.95, 6.40, 140, 0.95, 0, 3.0, 4, 0.0002, 1}, /* 128 */ 254 {160, 9, 9, 1, 1.79, 6.00, 135, 0.95, -2, 5.0, 3.5, 0, 1}, /* 160 */ 255 {192, 9, 9, 1, 1.49, 5.60, 125, 0.97, -4, 7.0, 3, 0, 0}, /* 192 */ 256 {224, 9, 9, 1, 1.25, 5.20, 125, 0.98, -6, 9.0, 2, 0, 0}, /* 224 */ 257 {256, 9, 9, 1, 0.97, 5.20, 125, 1.00, -8, 10.0, 1, 0, 0}, /* 256 */ 258 {320, 9, 9, 1, 0.90, 5.20, 125, 1.00, -10, 12.0, 0, 0, 0} /* 320 */ 259 }; 260 261 /* *INDENT-ON* */ 262 263 /* Variables for the ABR stuff */ 264 int r; 265 int actual_bitrate = preset; 266 267 r = nearestBitrateFullIndex(preset); 268 269 (void) lame_set_VBR(gfp, vbr_abr); 270 (void) lame_set_VBR_mean_bitrate_kbps(gfp, (actual_bitrate)); 271 (void) lame_set_VBR_mean_bitrate_kbps(gfp, min_int(lame_get_VBR_mean_bitrate_kbps(gfp), 320)); 272 (void) lame_set_VBR_mean_bitrate_kbps(gfp, max_int(lame_get_VBR_mean_bitrate_kbps(gfp), 8)); 273 (void) lame_set_brate(gfp, lame_get_VBR_mean_bitrate_kbps(gfp)); 274 275 276 /* parameters for which there is no proper set/get interface */ 277 if (abr_switch_map[r].safejoint > 0) 278 (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2); /* safejoint */ 279 280 if (abr_switch_map[r].sfscale > 0) 281 (void) lame_set_sfscale(gfp, 1); 282 283 284 SET_OPTION(quant_comp, abr_switch_map[r].quant_comp, -1); 285 SET_OPTION(quant_comp_short, abr_switch_map[r].quant_comp_s, -1); 286 287 SET__OPTION(msfix, abr_switch_map[r].nsmsfix, -1); 288 289 SET_OPTION(short_threshold_lrm, abr_switch_map[r].st_lrm, -1); 290 SET_OPTION(short_threshold_s, abr_switch_map[r].st_s, -1); 291 292 /* ABR seems to have big problems with clipping, especially at low bitrates */ 293 /* so we compensate for that here by using a scale value depending on bitrate */ 294 lame_set_scale(gfp, lame_get_scale(gfp) * abr_switch_map[r].scale); 295 296 SET_OPTION(maskingadjust, abr_switch_map[r].masking_adj, 0); 297 if (abr_switch_map[r].masking_adj > 0) { 298 SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * .9, 0); 299 } 300 else { 301 SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * 1.1, 0); 302 } 303 304 305 SET_OPTION(ATHlower, abr_switch_map[r].ath_lower, 0); 306 SET_OPTION(ATHcurve, abr_switch_map[r].ath_curve, -1); 307 308 SET_OPTION(interChRatio, abr_switch_map[r].interch, -1); 309 310 (void) abr_switch_map[r].abr_kbps; 311 312 gfp->internal_flags->cfg.minval = 5. * (abr_switch_map[r].abr_kbps / 320.); 313 314 return preset; 315} 316 317 318 319int 320apply_preset(lame_global_flags * gfp, int preset, int enforce) 321{ 322 /*translate legacy presets */ 323 switch (preset) { 324 case R3MIX: 325 { 326 preset = V3; 327 (void) lame_set_VBR(gfp, vbr_mtrh); 328 break; 329 } 330 case MEDIUM: 331 case MEDIUM_FAST: 332 { 333 preset = V4; 334 (void) lame_set_VBR(gfp, vbr_mtrh); 335 break; 336 } 337 case STANDARD: 338 case STANDARD_FAST: 339 { 340 preset = V2; 341 (void) lame_set_VBR(gfp, vbr_mtrh); 342 break; 343 } 344 case EXTREME: 345 case EXTREME_FAST: 346 { 347 preset = V0; 348 (void) lame_set_VBR(gfp, vbr_mtrh); 349 break; 350 } 351 case INSANE: 352 { 353 preset = 320; 354 gfp->preset = preset; 355 (void) apply_abr_preset(gfp, preset, enforce); 356 lame_set_VBR(gfp, vbr_off); 357 return preset; 358 } 359 } 360 361 gfp->preset = preset; 362 { 363 switch (preset) { 364 case V9: 365 apply_vbr_preset(gfp, 9, enforce); 366 return preset; 367 case V8: 368 apply_vbr_preset(gfp, 8, enforce); 369 return preset; 370 case V7: 371 apply_vbr_preset(gfp, 7, enforce); 372 return preset; 373 case V6: 374 apply_vbr_preset(gfp, 6, enforce); 375 return preset; 376 case V5: 377 apply_vbr_preset(gfp, 5, enforce); 378 return preset; 379 case V4: 380 apply_vbr_preset(gfp, 4, enforce); 381 return preset; 382 case V3: 383 apply_vbr_preset(gfp, 3, enforce); 384 return preset; 385 case V2: 386 apply_vbr_preset(gfp, 2, enforce); 387 return preset; 388 case V1: 389 apply_vbr_preset(gfp, 1, enforce); 390 return preset; 391 case V0: 392 apply_vbr_preset(gfp, 0, enforce); 393 return preset; 394 default: 395 break; 396 } 397 } 398 if (8 <= preset && preset <= 320) { 399 return apply_abr_preset(gfp, preset, enforce); 400 } 401 402 gfp->preset = 0; /*no corresponding preset found */ 403 return preset; 404} 405