X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fparameter_descriptor.cc;h=4f26af997d843087dca66a5c4d4ea6f5a7620ee6;hb=84272b4e27e537bf2c38c9cd25675c61addea40a;hp=9e02bc01ab1d3953a043af612cfbc599e29685f4;hpb=7ed775a716de655cee496e925fe062f6603abc0e;p=ardour.git diff --git a/libs/ardour/parameter_descriptor.cc b/libs/ardour/parameter_descriptor.cc index 9e02bc01ab..4f26af997d 100644 --- a/libs/ardour/parameter_descriptor.cc +++ b/libs/ardour/parameter_descriptor.cc @@ -157,13 +157,22 @@ ParameterDescriptor::update_steps() if (toggled || enumeration) { logarithmic = false; } + if (logarithmic && sr_dependent && upper > lower && lower == 0) { + /* work-around for plugins with a log-scale control 0..SR; log (0) is not defined */ + 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; } @@ -174,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 @@ -184,45 +200,39 @@ ParameterDescriptor::update_steps() largestep = position_to_gain (dB_coeff_step(upper)); step = position_to_gain (largestep / 10.0); smallstep = step; + } else if (logarithmic) { + /* ignore logscale rangesteps. {small|large}steps are used with the spinbox. + * gtk-spinbox shows the internal (not interface) value and up/down + * arrows linearly increase. + * The AutomationController uses internal_to_interface(): + * ui-step [0..1] -> log (1 + largestep / lower) / log (upper / lower) + * so we use a step that's a multiple of "lower" for the interface step: + * log (1 + x) / log (upper / lower) + */ + smallstep = step = lower / 11; + largestep = lower / 3; + /* NOTE: the actual value does use rangesteps via + * logscale_to_position_with_steps(), position_to_logscale_with_steps() + * when it is converted. + */ } 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); - } else if (integer_step) { - smallstep = 1.0; - step = std::max(1.f, rintf (rangesteps)); - largestep = std::max(1.f, rintf (largestep)); + if (integer_step) { + smallstep = step = 1.0; + largestep = std::max(1.f, rintf (delta / (rangesteps - 1.f))); + } else { + step = smallstep = delta / (rangesteps - 1.f); + largestep = std::min ((delta / 4.0f), 10.f * smallstep); } } 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); - - 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); - } else if (integer_step) { - smallstep = 1.0; - step = std::max(1.f, rintf (step)); - largestep = std::max(1.f, rintf (largestep)); + /* 30 steps between min/max (300 for fine-grained) */ + if (integer_step) { + smallstep = step = 1.0; + largestep = std::max(1.f, rintf (delta / 30.f)); + } else { + step = smallstep = (delta / 300.0f); + largestep = (delta / 30.0f); } } } @@ -383,10 +393,10 @@ ParameterDescriptor::from_interface (float val) const * e.g. 5 integers 0,1,2,3,4 are mapped to a fader * [0.0 .. 0.2 | 0.2 .. 0.4 | 0.4 .. 0.6 | 0.6 .. 0.8 | 0.8 .. 1.0] */ - val = round (lower + val * (1.f + upper - lower) - .5f); + val = floor (lower + val * (1.f + upper - lower)); } else if (rangesteps > 1) { /* similar to above, but for float controls */ - val = floor (val * (rangesteps - 1.f)) / (rangesteps - 1.f); // XXX + val = round (val * (rangesteps - 1.f)) / (rangesteps - 1.f); // XXX val = val * (upper - lower) + lower; } else { val = val * (upper - lower) + lower;