From e91b80eb85452586f226f4b7eb84d8be36ea1a3c Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 19 Jun 2017 00:28:43 +0200 Subject: Centralize control-parameter math functions in libpbd. Functions formerly in ardour/util.h and some more functions. The main motivation is libevoral which can use libpbd but not libardour. The eventual goal is to consolidate various different interpolation, scaling and deflection methods. --- libs/pbd/pbd/control_math.h | 105 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 libs/pbd/pbd/control_math.h (limited to 'libs/pbd') diff --git a/libs/pbd/pbd/control_math.h b/libs/pbd/pbd/control_math.h new file mode 100644 index 0000000000..8ead1c918a --- /dev/null +++ b/libs/pbd/pbd/control_math.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2017 Robin Gareus + * Copyright (C) 1999 Paul Davis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __pbd_control_math_h__ +#define __pbd_control_math_h__ + +#include +#include + +/* map gain-coeff [0..2] to position [0..1] */ +static inline double +gain_to_position (double g) +{ + if (g == 0) { + return 0; + } + return pow ((6.0 * log (g) / log (2.0) + 192.0) / 198.0, 8.0); +} + +/* map position [0..1] to gain-coeff [0..2] */ +static inline double +position_to_gain (double pos) +{ + if (pos == 0.0) { + return 0.0; + } + return exp (((pow (pos, 1.0 / 8.0) * 198.0) - 192.0) / 6.0 * log (2.0)); +} + +/* map position [0..1] to parameter [lower..upper] on a logarithmic scale */ +static inline double +position_to_logscale (double pos, double lower, double upper) +{ + assert (upper > lower && lower * upper > 0); + assert (pos >= 0.0 && pos <= 1.0); + return lower * pow (upper / lower, pos); +} + +/* map parameter [lower..upper] to position [0..1] on a logarithmic scale*/ +static inline double +logscale_to_position (double val, double lower, double upper) +{ + assert (upper > lower && lower * upper > 0); + assert (val >= lower && val <= upper); + return log (val / lower) / log (upper / lower); +} + +static inline double +logscale_to_position_with_steps (double val, double lower, double upper, uint32_t steps) +{ + assert (steps > 1); + double v = logscale_to_position (val, lower, upper) * (steps - 1.0); + return round (v) / (steps - 1.0); +} + +static inline double +position_to_logscale_with_steps (double pos, double lower, double upper, uint32_t steps) +{ + assert (steps > 1); + double p = round (pos * (steps - 1.0)) / (steps - 1.0); + return position_to_logscale (p, lower, upper); +} + + +static inline double +interpolate_linear (double from, double to, double fraction) +{ + return from + (fraction * (to - from)); +} + +static inline double +interpolate_logarithmic (double from, double to, double fraction, double lower, double upper) +{ + // this is expensive -- optimize + double l0 = logscale_to_position (from, lower, upper); + double l1 = logscale_to_position (to, lower, upper); + return position_to_logscale (l0 + fraction * (l1 - l0), lower, upper); +} + +static inline double +interpolate_gain (double from, double to, double fraction, double upper) +{ + // this is expensive -- optimize + double g0 = gain_to_position (from * 2. / upper); + double g1 = gain_to_position (to * 2. / upper); + return position_to_gain (g0 + fraction * (g1 - g0)) * upper / 2.; +} + +#endif -- cgit v1.2.3