LADSPA logarithmic handling patches from nickm and robsch
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 1 Oct 2009 16:42:02 +0000 (16:42 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 1 Oct 2009 16:42:02 +0000 (16:42 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@5705 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ladspa_plugin.cc
libs/gtkmm2ext/barcontroller.cc
libs/gtkmm2ext/gtkmm2ext/barcontroller.h

index 852587896ea6c6d71604cdd6cc320f847177fbd3..06a67aca0880d14e2fbdfe36fe4d92ede9f326e6 100644 (file)
@@ -178,34 +178,44 @@ LadspaPlugin::default_value (uint32_t port)
                        ret = prh[port].LowerBound;
                        bounds_given = true;
                        sr_scaling = true;
-                       earlier_hint = true;
                }
                
                /* FIXME: add support for logarithmic defaults */
                
                else if (LADSPA_IS_HINT_DEFAULT_LOW(prh[port].HintDescriptor)) {
-                       ret = prh[port].LowerBound * 0.75f + prh[port].UpperBound * 0.25f;
+                       if (LADSPA_IS_HINT_LOGARITHMIC(prh[port].HintDescriptor)) {
+                               ret = exp(log(prh[port].LowerBound) * 0.75f + log(prh[port].UpperBound) * 0.25f);
+                       }
+                       else {
+                               ret = prh[port].LowerBound * 0.75f + prh[port].UpperBound * 0.25f;
+                       }
                        bounds_given = true;
                        sr_scaling = true;
-                       earlier_hint = true;
                }
                else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(prh[port].HintDescriptor)) {
-                       ret = prh[port].LowerBound * 0.50f + prh[port].UpperBound * 0.50f;
+                       if (LADSPA_IS_HINT_LOGARITHMIC(prh[port].HintDescriptor)) {
+                               ret = exp(log(prh[port].LowerBound) * 0.5f + log(prh[port].UpperBound) * 0.5f);
+                       }
+                       else {
+                               ret = prh[port].LowerBound * 0.5f + prh[port].UpperBound * 0.5f;
+                       }
                        bounds_given = true;
                        sr_scaling = true;
-                       earlier_hint = true;
                }
                else if (LADSPA_IS_HINT_DEFAULT_HIGH(prh[port].HintDescriptor)) {
-                       ret = prh[port].LowerBound * 0.25f + prh[port].UpperBound * 0.75f;
+                       if (LADSPA_IS_HINT_LOGARITHMIC(prh[port].HintDescriptor)) {
+                               ret = exp(log(prh[port].LowerBound) * 0.25f + log(prh[port].UpperBound) * 0.75f);
+                       }
+                       else {
+                               ret = prh[port].LowerBound * 0.25f + prh[port].UpperBound * 0.75f;
+                       }
                        bounds_given = true;
                        sr_scaling = true;
-                       earlier_hint = true;
                }
                else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(prh[port].HintDescriptor)) {
                        ret = prh[port].UpperBound;
                        bounds_given = true;
                        sr_scaling = true;
-                       earlier_hint = true;
                }
                else if (LADSPA_IS_HINT_DEFAULT_0(prh[port].HintDescriptor)) {
                        ret = 0.0f;
index 53d642ce23f7ee1f63579d4b9a677130f93a0c2f..5cce612056c59b52cf680a5ee8a41abe2ccd23bc 100644 (file)
@@ -18,6 +18,7 @@
 */
 
 #include <string>
+#include <sstream>
 #include <climits>
 #include <cstdio>
 #include <cmath>
@@ -48,6 +49,7 @@ BarController::BarController (Gtk::Adjustment& adj,
        switching = false;
        switch_on_release = false;
        use_parent = false;
+       logarithmic = false;
 
        layout = darea.create_pango_layout("");
 
@@ -76,6 +78,7 @@ BarController::BarController (Gtk::Adjustment& adj,
        spinner.signal_input().connect (mem_fun (*this, &BarController::entry_input));
        spinner.signal_output().connect (mem_fun (*this, &BarController::entry_output));
        spinner.set_digits (3);
+       spinner.set_numeric (true);
 
        add (darea);
        show_all ();
@@ -422,13 +425,6 @@ BarController::switch_to_spinner ()
 void
 BarController::entry_activated ()
 {
-       string text = spinner.get_text ();
-       float val;
-
-       if (sscanf (text.c_str(), "%f", &val) == 1) {
-               adjustment.set_value (val);
-       }
-       
        switch_to_bar ();
 }
 
@@ -453,16 +449,84 @@ BarController::set_sensitive (bool yn)
        darea.set_sensitive (yn);
 }
 
-bool
-BarController::entry_input (double* /*v*/)
+/* 
+    This is called when we need to update the adjustment with the value
+    from the spinner's text entry.
+    
+    We need to use Gtk::Entry::get_text to avoid recursive nastiness :)
+    
+    If we're not in logarithmic mode we can return false to use the 
+    default conversion.
+    
+    In theory we should check for conversion errors but set numeric
+    mode to true on the spinner prevents invalid input.
+*/
+int
+BarController::entry_input (double* new_value)
 {
-       return false;
+       if (!logarithmic) {
+               return false;
+       }
+
+       // extract a double from the string and take its log
+       Entry *entry = dynamic_cast<Entry *>(&spinner);
+       stringstream stream(entry->get_text());
+       stream.imbue(std::locale(""));
+
+       double value;
+       stream >> value;
+       
+       *new_value = log(value);
+       return true;
 }
 
+/* 
+    This is called when we need to update the spinner's text entry 
+    with the value of the adjustment.
+    
+    We need to use Gtk::Entry::set_text to avoid recursive nastiness :)
+    
+    If we're not in logarithmic mode we can return false to use the 
+    default conversion.
+*/
 bool
 BarController::entry_output ()
 {
-       return false;
+       if (!logarithmic) {
+               return false;
+       }
+
+       // generate the exponential and turn it into a string
+       // convert to correct locale. 
+       
+       stringstream stream;
+       string str;
+       size_t found;
+
+       // Gtk.Entry does not like the thousands separator, so we have to  
+       // remove it after conversion from float to string.
+
+       stream.imbue(std::locale(""));
+       stream.precision(spinner.get_digits());
+
+       stream << fixed << exp(spinner.get_adjustment()->get_value());
+       
+       str=stream.str();
+
+       // find thousands separators, remove them
+       found = str.find(use_facet<numpunct<char> >(std::locale("")).thousands_sep());
+       while(found != str.npos) {
+               str.erase(found,1);
+
+               //find next
+               found = str.find(use_facet<numpunct<char> >(std::locale("")).thousands_sep());
+       }
+
+       Entry *entry = dynamic_cast<Entry *>(&spinner);
+       entry->set_text(str);
+       
+       return true;
 }
 
+
        
index e5c01c719161e14dfb35fe806a92e85b856996ff..176580dece63a7ab506eb4ef21ff3760d5c8d647 100644 (file)
@@ -48,6 +48,8 @@ class BarController : public Gtk::Frame
        void set_use_parent (bool yn);
 
        void set_sensitive (bool yn);
+       
+       void set_logarithmic (bool yn) { logarithmic = yn; }
 
        sigc::signal<void> StartGesture;
        sigc::signal<void> StopGesture;
@@ -73,6 +75,7 @@ class BarController : public Gtk::Frame
        GdkWindow*          grab_window;
        Gtk::SpinButton     spinner;
        bool                use_parent;
+       bool                logarithmic;
 
        virtual std::string get_label (int& /*x*/) {
                return "";
@@ -94,6 +97,9 @@ class BarController : public Gtk::Frame
 
        void entry_activated ();
        void drop_grab ();
+       
+       int entry_input (double* new_value);
+       bool entry_output ();
 };