Consistently set parameter steps.
And it's actually mostly moot. interface_to_internal maps any range to 0..1. The GUI could just hardcode min/max 0, 1 and steps 1/30, 1/300. Except for controls that have explicit range-steps & ctrl surfaces.
This commit is contained in:
parent
f66b863a2d
commit
73ad5c97f2
@ -162,12 +162,17 @@ ParameterDescriptor::update_steps()
|
||||
lower = upper / 1000.f;
|
||||
}
|
||||
if (logarithmic && (upper <= lower || lower * upper <= 0)) {
|
||||
/* log-scale params need upper > lower and both values need the same sign */
|
||||
logarithmic = false;
|
||||
}
|
||||
if (rangesteps < 2) {
|
||||
rangesteps = 0;
|
||||
}
|
||||
if (enumeration) {
|
||||
/* enums need scale-points.
|
||||
* The GUI is more restrictive, a dropdown is displayed
|
||||
* IIF scale_points.size() == (1 + upper - lower)
|
||||
*/
|
||||
if (!scale_points || scale_points->empty ()) {
|
||||
enumeration = false;
|
||||
}
|
||||
@ -178,6 +183,13 @@ ParameterDescriptor::update_steps()
|
||||
}
|
||||
}
|
||||
|
||||
/* upper == lower does not make any sense */
|
||||
if (lower == upper) {
|
||||
upper = lower + 0.01; // add some arbitrary value
|
||||
}
|
||||
|
||||
/* set steps */
|
||||
|
||||
if (unit == ParameterDescriptor::MIDI_NOTE) {
|
||||
step = smallstep = 1; // semitone
|
||||
largestep = 12; // octave
|
||||
@ -190,43 +202,28 @@ ParameterDescriptor::update_steps()
|
||||
smallstep = step;
|
||||
} else if (rangesteps > 1) {
|
||||
const float delta = upper - lower;
|
||||
|
||||
step = smallstep = (delta / (rangesteps - 1)); // XXX
|
||||
largestep = std::min ((delta / 5.0f), 10.f * smallstep); // XXX
|
||||
|
||||
if (logarithmic) {
|
||||
smallstep = smallstep / logf (rangesteps); // XXX
|
||||
step = step / logf (rangesteps);
|
||||
largestep = largestep / logf (rangesteps);
|
||||
smallstep = step = (powf (delta, 1.f / (float)rangesteps) - 1.f) * lower;
|
||||
largestep = (powf (delta, std::max (0.5f, 10.f / (float)rangesteps)) - 1.f) * lower;
|
||||
} else if (integer_step) {
|
||||
smallstep = 1.0;
|
||||
step = std::max(1.f, rintf (rangesteps));
|
||||
largestep = std::max(1.f, rintf (largestep));
|
||||
smallstep = step = 1.0;
|
||||
largestep = std::max(1.f, rintf (delta / (rangesteps - 1)));
|
||||
} else {
|
||||
step = smallstep = delta / (rangesteps - 1);
|
||||
largestep = std::min ((delta / 4.0f), 10.f * smallstep); // XXX
|
||||
}
|
||||
} else {
|
||||
const float delta = upper - lower;
|
||||
|
||||
/* 30 happens to be the total number of steps for a fader with default
|
||||
max gain of 2.0 (6 dB), so we use 30 here too for consistency. */
|
||||
step = smallstep = (delta / 300.0f);
|
||||
largestep = (delta / 30.0f);
|
||||
|
||||
/* 30 steps between min/max (300 for fine-grained) */
|
||||
if (logarithmic) {
|
||||
/* Steps are linear, but we map them with pow like values (in
|
||||
internal_to_interface). Thus, they are applied exponentially,
|
||||
which means too few steps. So, divide to get roughly the
|
||||
desired number of steps (30). This is not mathematically
|
||||
precise but seems to be about right for the controls I tried.
|
||||
If you're reading this, you've probably found a case where that
|
||||
isn't true, and somebody needs to sit down with a piece of paper
|
||||
and actually do the math. */
|
||||
smallstep = smallstep / logf(30.0f);
|
||||
step = step / logf(30.0f);
|
||||
largestep = largestep / logf(30.0f);
|
||||
smallstep = step = (powf (delta, 1.f / 300.f) - 1.f) * lower;
|
||||
largestep = (powf (delta, 1.f / 30.f) - 1.f) * lower;
|
||||
} else if (integer_step) {
|
||||
smallstep = 1.0;
|
||||
step = std::max(1.f, rintf (step));
|
||||
largestep = std::max(1.f, rintf (largestep));
|
||||
smallstep = step = 1.0;
|
||||
largestep = std::max(1.f, rintf (delta / 30.f));
|
||||
} else {
|
||||
step = smallstep = (delta / 300.0f);
|
||||
largestep = (delta / 30.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -342,27 +342,22 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc)
|
||||
desc.upper = 1.0;
|
||||
}
|
||||
|
||||
if (prop.flags & kVstParameterUsesIntStep) {
|
||||
const float range = desc.upper - desc.lower;
|
||||
|
||||
if (prop.flags & kVstParameterUsesIntStep && prop.stepInteger < range) {
|
||||
desc.step = prop.stepInteger;
|
||||
desc.smallstep = prop.stepInteger;
|
||||
desc.largestep = prop.stepInteger;
|
||||
desc.integer_step = true;
|
||||
|
||||
} else if (prop.flags & kVstParameterUsesFloatStep) {
|
||||
|
||||
desc.rangesteps = 1 + ceilf (range / desc.step);
|
||||
} else if (prop.flags & kVstParameterUsesFloatStep && prop.stepFloat < range) {
|
||||
desc.step = prop.stepFloat;
|
||||
desc.smallstep = prop.smallStepFloat;
|
||||
desc.largestep = prop.largeStepFloat;
|
||||
// desc.rangesteps = (desc.upper - desc.lower) / prop.smallStepFloat; // XXX
|
||||
|
||||
desc.rangesteps = 1 + ceilf (range / desc.step);
|
||||
} else {
|
||||
|
||||
float range = desc.upper - desc.lower;
|
||||
|
||||
desc.step = range / 100.0f;
|
||||
desc.smallstep = desc.step / 2.0f;
|
||||
desc.largestep = desc.step * 10.0f;
|
||||
desc.smallstep = desc.step = range / 300.0f;
|
||||
desc.largestep = range / 30.0f;
|
||||
}
|
||||
|
||||
if (strlen(prop.label) == 0) {
|
||||
@ -385,11 +380,16 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc)
|
||||
desc.label = Glib::locale_to_utf8 (label);
|
||||
desc.lower = 0.0f;
|
||||
desc.upper = 1.0f;
|
||||
desc.step = 0.01f;
|
||||
desc.smallstep = 0.005f;
|
||||
desc.largestep = 0.1f;
|
||||
desc.smallstep = desc.step = 1.f / 300.f;
|
||||
desc.largestep = 1.f / 30.f;
|
||||
}
|
||||
|
||||
/* TODO we should really call
|
||||
* desc.update_steps ()
|
||||
* instead of manually assigning steps. Yet, VST prop is (again)
|
||||
* the odd one out compared to other plugin formats.
|
||||
*/
|
||||
|
||||
if (_parameter_defaults.find (which) == _parameter_defaults.end ()) {
|
||||
_parameter_defaults[which] = get_parameter (which);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user