Optimize automation-event process splitting
[ardour.git] / gtk2_ardour / transform_dialog.cc
index 35df027187968669429d827bda423b2e7b444893..6eed4e10d72dcf99dff171a995ba05c940116eef 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "transform_dialog.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace Gtk;
@@ -69,7 +69,7 @@ TransformDialog::Model::Model()
        }
 
        static const char* operator_labels[] = {
-               /* no PUSH */ "+", "-", "*", "/", NULL
+               /* no PUSH */ "+", "-", "*", "/", "mod", NULL
        };
        for (int o = 0; operator_labels[o]; ++o) {
                Gtk::TreeModel::Row row = *(operator_list->append());
@@ -114,6 +114,7 @@ TransformDialog::TransformDialog()
 
        show_all();
        _seed_chooser->value_spinner.hide();
+       _seed_chooser->source_changed();
 }
 
 TransformDialog::ValueChooser::ValueChooser(const Model& model)
@@ -172,13 +173,16 @@ set_spinner_for(Gtk::SpinButton&                     spinner,
                spinner.set_digits(2);
                break;
        case MidiModel::NoteDiffCommand::Channel:
-               spinner.get_adjustment()->set_lower(0);
-               spinner.get_adjustment()->set_upper(15);
+               spinner.get_adjustment()->set_lower(1);
+               spinner.get_adjustment()->set_upper(16);
                spinner.get_adjustment()->set_step_increment(1);
                spinner.get_adjustment()->set_page_increment(10);
                spinner.set_digits(0);
                break;
        }
+       spinner.set_value(
+               std::min(spinner.get_adjustment()->get_upper(),
+                        std::max(spinner.get_adjustment()->get_lower(), spinner.get_value())));
 }
 
 void
@@ -224,6 +228,18 @@ TransformDialog::ValueChooser::source_changed()
        }
 }
 
+double
+TransformDialog::ValueChooser::get_value () const
+{
+               return value_spinner.get_value() + ((target_property == MidiModel::NoteDiffCommand::Channel) ? -1. : 0.);
+}
+
+double
+TransformDialog::ValueChooser::get_max () const
+{
+               return max_spinner.get_value() + ((target_property == MidiModel::NoteDiffCommand::Channel) ? -1. : 0.);
+}
+
 void
 TransformDialog::ValueChooser::get(std::list<Operation>& ops)
 {
@@ -233,13 +249,13 @@ TransformDialog::ValueChooser::get(std::list<Operation>& ops)
        if (source == Transform::Value::RANDOM) {
                /* Special case: a RANDOM value is always 0..1, so here we produce some
                   code to produce a random number in a range: "rand value *". */
-               const double a     = value_spinner.get_value();
-               const double b     = max_spinner.get_value();
+               const double a     = get_value();
+               const double b     = get_max();
                const double min   = std::min(a, b);
                const double max   = std::max(a, b);
                const double range = max - min;
 
-               // "rand range * min +" (i.e. (rand * range) + min)
+               // "rand range * min +" ((rand * range) + min)
                ops.push_back(Operation(Operation::PUSH, Value(Value::RANDOM)));
                ops.push_back(Operation(Operation::PUSH, Value(range)));
                ops.push_back(Operation(Operation::MULT));
@@ -250,15 +266,17 @@ TransformDialog::ValueChooser::get(std::list<Operation>& ops)
                /* Special case: hijack NOWHERE for ramps (see above).  The language
                   knows nothing of ramps, we generate code to calculate the
                   appropriate value here. */
-               const double first = value_spinner.get_value();
-               const double last  = max_spinner.get_value();
+               const double first = get_value();
+               const double last  = get_max();
                const double rise  = last - first;
 
-               // "index rise * n_notes / first +" (i.e. index * rise / n_notes + first)
+               // "index rise * n_notes 1 - / first +" (index * rise / (n_notes - 1) + first)
                ops.push_back(Operation(Operation::PUSH, Value(Value::INDEX)));
                ops.push_back(Operation(Operation::PUSH, Value(rise)));
                ops.push_back(Operation(Operation::MULT));
                ops.push_back(Operation(Operation::PUSH, Value(Value::N_NOTES)));
+               ops.push_back(Operation(Operation::PUSH, Value(1)));
+               ops.push_back(Operation(Operation::SUB));
                ops.push_back(Operation(Operation::DIV));
                ops.push_back(Operation(Operation::PUSH, Value(first)));
                ops.push_back(Operation(Operation::ADD));
@@ -274,7 +292,7 @@ TransformDialog::ValueChooser::get(std::list<Operation>& ops)
        } else if (val.source == Transform::Value::LITERAL) {
                val.value = Variant(
                        MidiModel::NoteDiffCommand::value_type(target_property),
-                       value_spinner.get_value());
+                       get_value());
        }
        ops.push_back(Operation(Operation::PUSH, val));
 }
@@ -303,6 +321,7 @@ TransformDialog::OperationChooser::OperationChooser(const Model& model)
        show_all();
        value_chooser.property_combo.hide();
        value_chooser.value_spinner.set_value(1);
+       value_chooser.source_changed();
 }
 
 void