xref: /third_party/lame/libmp3lame/presets.c (revision 159b3361)
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