Skip to content

Commit 14f7cd2

Browse files
author
Guillaume Piolat
committed
[dplug:client] New type of parameter, the BipolarFloatParameter.
It allows to have an exponentiation mapping but favors the "zero" zone between two extrema that are "unwise". eg: mallocNew!BipolarFloatParameter(paramDelay, "Haas Delay", "ms", -200.0, 200, 0, 2.0).withDecimalPrecision(0)); At normalized position 0, the parameter's value is -200.0 At normalized position 0.25, the parameter's value is -14.1421 At normalized position 0.5, the parameter's value is 0 At normalized position 0.75, the parameter's value is +14.1421 At normalized position 1, the parameter's value is +200.0
1 parent 5a38db1 commit 14f7cd2

File tree

1 file changed

+85
-6
lines changed

1 file changed

+85
-6
lines changed

client/dplug/client/params.d

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,10 +1103,17 @@ private:
11031103
double _shape;
11041104
}
11051105

1106-
/// Float parameter following a x^N type mapping (eg: something that doesn't fit in the other categories)
1106+
/// Float parameter following a x^N type mapping
1107+
/// (eg: something that doesn't fit in the other categories)
1108+
///
1109+
/// To go normalized: min to max => 0 to 1 => exponentiation
1110+
/// Note: when `shape` is 1.0, this is simply a `LinearFloatParameter`.
11071111
class PowFloatParameter : FloatParameter
11081112
{
1109-
this(int index, string name, string label, double min, double max, double defaultValue, double shape) nothrow @nogc
1113+
nothrow:
1114+
@nogc:
1115+
1116+
this(int index, string name, string label, double min, double max, double defaultValue, double shape)
11101117
{
11111118
super(index, name, label, min, max, defaultValue);
11121119
_shape = shape;
@@ -1121,10 +1128,12 @@ class PowFloatParameter : FloatParameter
11211128
v = 1.0;
11221129
v = v ^^ (1 / _shape);
11231130

1124-
// Note: It's not entirely impossible to imagine a particular way that 1 would be exceeded, since pow
1125-
// is implemented with an exp approximation and a log approximation.
1126-
// TODO: produce ill case in isolation to see
1127-
assert(v >= 0 && v <= 1); // will still assert on NaN
1131+
// Note: It's not entirely impossible to imagine a particular
1132+
// way that 1 would be exceeded, since `pow` is implemented
1133+
// with an exp approximation and a log approximation.
1134+
if (v > 1)
1135+
v = 1;
1136+
11281137
return v;
11291138
}
11301139

@@ -1141,3 +1150,73 @@ class PowFloatParameter : FloatParameter
11411150
private:
11421151
double _shape;
11431152
}
1153+
1154+
1155+
/// Float parameter following a x^N type mapping like `PowFloatParameter`,
1156+
/// but this exponentiation happens as if from -1 to 1 instead of from 0 to 1.
1157+
///
1158+
/// This allows to model parameters who get a large maximum value,
1159+
/// while still favouring reasonable values around the center.
1160+
///
1161+
/// To go normalized: min to max => -1 to 1 => exponentiation => 0 to 1
1162+
/// Note: when `shape` is 1.0, this is simply a `LinearFloatParameter`.
1163+
class BipolarFloatParameter : FloatParameter
1164+
{
1165+
nothrow:
1166+
@nogc:
1167+
1168+
this(int index, string name, string label, double min, double max, double defaultValue, double shape)
1169+
{
1170+
super(index, name, label, min, max, defaultValue);
1171+
_shape = shape;
1172+
}
1173+
1174+
override double toNormalized(double value)
1175+
{
1176+
// map to [-1, 1]
1177+
double v = -1.0 + 2.0 * (value - _min) / (_max - _min);
1178+
if (v < -1.0) v = -1.0;
1179+
if (v > 1.0) v = 1.0;
1180+
1181+
// signed pow
1182+
double sign = v >= 0.0 ? +1 : -1;
1183+
if (v < 0) v = -v;
1184+
assert(v >= 0);
1185+
v = sign * (v ^^ (1 / _shape));
1186+
1187+
// map to [0, 1]
1188+
v = 0.5 * (v + 1);
1189+
if (v < -1.0) v = -1.0;
1190+
if (v > 1.0) v = 1.0;
1191+
1192+
return v;
1193+
}
1194+
1195+
override double fromNormalized(double normalizedValue)
1196+
{
1197+
// map to [-1, 1]
1198+
normalizedValue = -1 + 2 * normalizedValue;
1199+
1200+
// sign pow
1201+
double sign = normalizedValue >= 0 ? +1 : -1;
1202+
if (normalizedValue < 0) normalizedValue = -normalizedValue;
1203+
assert(normalizedValue >= 0);
1204+
double v = (normalizedValue ^^ _shape) * sign;
1205+
1206+
// map to [0, 1]
1207+
v = 0.5 * (v + 1);
1208+
if (v < -1.0) v = -1.0;
1209+
if (v > 1.0) v = 1.0;
1210+
1211+
// map to [min, max]
1212+
v = _min + v * (_max - _min);
1213+
if (v < _min)
1214+
v = _min;
1215+
if (v > _max)
1216+
v = _max;
1217+
return v;
1218+
}
1219+
1220+
private:
1221+
double _shape;
1222+
}

0 commit comments

Comments
 (0)