Przeglądaj źródła

Piano: Respect logarithmic parameters in sliders

If the underlying parameter is logarithmic, the slider respects that and
switches to a logarithmic display. Currently, the used base is e, and
we'll have to see in practice if 2 or 10 might be better. The parameters
that make use of this, as can be seen in the previous commit, are all of
the time dependent parameters such as the synth envelope parameters, as
with these, usually fine-grained control at small time scales and
coarser control at large time scales is desired.

This was a good opportunity to refactor the slider step count into a
constant.
kleines Filmröllchen 3 lat temu
rodzic
commit
889315e8aa

+ 22 - 4
Userland/Applications/Piano/ProcessorParameterWidget/Slider.cpp

@@ -6,21 +6,36 @@
 
 
 #include "Slider.h"
 #include "Slider.h"
 #include "WidgetWithLabel.h"
 #include "WidgetWithLabel.h"
+#include <AK/FixedPoint.h>
+#include <AK/Math.h>
 
 
 ProcessorParameterSlider::ProcessorParameterSlider(Orientation orientation, LibDSP::ProcessorRangeParameter& parameter, RefPtr<GUI::Label> value_label)
 ProcessorParameterSlider::ProcessorParameterSlider(Orientation orientation, LibDSP::ProcessorRangeParameter& parameter, RefPtr<GUI::Label> value_label)
     : Slider(orientation)
     : Slider(orientation)
     , WidgetWithLabel(move(value_label))
     , WidgetWithLabel(move(value_label))
     , m_parameter(parameter)
     , m_parameter(parameter)
 {
 {
-    set_range(m_parameter.min_value().raw(), m_parameter.max_value().raw());
-    set_value(m_parameter.value().raw());
-    set_step((m_parameter.min_value() - m_parameter.max_value()).raw() / 128);
+    if (!is_logarithmic()) {
+        set_range(m_parameter.min_value().raw(), m_parameter.max_value().raw());
+        set_value(m_parameter.value().raw());
+        set_step((m_parameter.min_value() - m_parameter.max_value()).raw() / slider_steps);
+    } else {
+        auto min_log = m_parameter.min_value().log2().raw();
+        auto max_log = m_parameter.max_value().log2().raw();
+        auto value_log = m_parameter.value().log2().raw();
+        set_range(min_log, max_log);
+        set_value(value_log);
+        set_step((min_log - max_log) / slider_steps);
+    }
     set_tooltip(m_parameter.name());
     set_tooltip(m_parameter.name());
     m_value_label->set_text(String::formatted("{:.2f}", static_cast<double>(m_parameter)));
     m_value_label->set_text(String::formatted("{:.2f}", static_cast<double>(m_parameter)));
 
 
     on_change = [this](auto value) {
     on_change = [this](auto value) {
         LibDSP::ParameterFixedPoint real_value;
         LibDSP::ParameterFixedPoint real_value;
         real_value.raw() = value;
         real_value.raw() = value;
+        if (is_logarithmic())
+            // FIXME: Implement exponential for fixed point
+            real_value = exp(static_cast<double>(real_value));
+
         m_parameter.set_value_sneaky(real_value, LibDSP::Detail::ProcessorParameterSetValueTag {});
         m_parameter.set_value_sneaky(real_value, LibDSP::Detail::ProcessorParameterSetValueTag {});
         if (m_value_label) {
         if (m_value_label) {
             double value = static_cast<double>(m_parameter);
             double value = static_cast<double>(m_parameter);
@@ -34,6 +49,9 @@ ProcessorParameterSlider::ProcessorParameterSlider(Orientation orientation, LibD
         }
         }
     };
     };
     m_parameter.did_change_value = [this](auto value) {
     m_parameter.did_change_value = [this](auto value) {
-        set_value(value.raw());
+        if (!is_logarithmic())
+            set_value(value.raw());
+        else
+            set_value(value.log2().raw());
     };
     };
 }
 }

+ 7 - 0
Userland/Applications/Piano/ProcessorParameterWidget/Slider.h

@@ -12,6 +12,8 @@
 #include <LibGUI/Slider.h>
 #include <LibGUI/Slider.h>
 #include <LibGfx/Orientation.h>
 #include <LibGfx/Orientation.h>
 
 
+constexpr int slider_steps = 256;
+
 class ProcessorParameterSlider
 class ProcessorParameterSlider
     : public GUI::Slider
     : public GUI::Slider
     , public WidgetWithLabel {
     , public WidgetWithLabel {
@@ -19,7 +21,12 @@ class ProcessorParameterSlider
 
 
 public:
 public:
     ProcessorParameterSlider(Orientation, LibDSP::ProcessorRangeParameter&, RefPtr<GUI::Label>);
     ProcessorParameterSlider(Orientation, LibDSP::ProcessorRangeParameter&, RefPtr<GUI::Label>);
+    constexpr bool is_logarithmic() const { return m_parameter.is_logarithmic() == LibDSP::Logarithmic::Yes; }
 
 
 protected:
 protected:
     LibDSP::ProcessorRangeParameter& m_parameter;
     LibDSP::ProcessorRangeParameter& m_parameter;
+
+private:
+    // Converts based on processor parameter boundaries.
+    int linear_to_logarithmic(int linear_value);
 };
 };