diff --git a/gtk2_ardour/varispeed_dialog.cc b/gtk2_ardour/varispeed_dialog.cc index e1f692afb6..ba0dbf20a2 100644 --- a/gtk2_ardour/varispeed_dialog.cc +++ b/gtk2_ardour/varispeed_dialog.cc @@ -18,6 +18,8 @@ #include +#include "pbd/unwind.h" + #include "varispeed_dialog.h" #include "ardour_ui.h" @@ -31,10 +33,13 @@ VarispeedDialog::VarispeedDialog () : ArdourDialog (_("Varispeed"), false) , _semitones_adjustment (0.0, -12.0, 12.0, 1.0, 4.0) , _cents_adjustment (0.0, -100.0, 100.0, 1.0, 10.0) + , _percent_adjustment (100.0, -50.0, 200.0, 1.0, 10.0) , _semitones_spinner (_semitones_adjustment) , _cents_spinner (_cents_adjustment) + , _percent_spinner (_percent_adjustment) + , ignore_changes (false) { - Table* t = manage (new Table (3, 2)); + Table* t = manage (new Table (5, 2)); t->set_row_spacings (6); t->set_col_spacings (6); @@ -49,14 +54,21 @@ VarispeedDialog::VarispeedDialog () t->attach (_cents_spinner, 1, 2, r, r + 1, FILL, EXPAND & FILL, 0, 0); ++r; + l = manage (new Label (_("Percentage:"), ALIGN_START, ALIGN_CENTER, false)); + t->attach (*l, 0, 1, r, r + 1, FILL, EXPAND, 0, 0); + t->attach (_percent_spinner, 1, 2, r, r + 1, FILL, EXPAND & FILL, 0, 0); + ++r; + get_vbox ()->set_spacing (6); get_vbox ()->pack_start (*t, false, false); _semitones_spinner.set_can_focus (false); _cents_spinner.set_can_focus (false); + _percent_spinner.set_can_focus (false); - _semitones_spinner.signal_changed ().connect (sigc::mem_fun (*this, &VarispeedDialog::apply_speed)); - _cents_spinner.signal_changed ().connect (sigc::mem_fun (*this, &VarispeedDialog::apply_speed)); + _semitones_spinner.signal_changed ().connect (sigc::mem_fun (*this, &VarispeedDialog::apply_semitones)); + _cents_spinner.signal_changed ().connect (sigc::mem_fun (*this, &VarispeedDialog::apply_semitones)); + _percent_spinner.signal_changed ().connect (sigc::mem_fun (*this, &VarispeedDialog::apply_percentage)); show_all_children (); } @@ -79,12 +91,42 @@ VarispeedDialog::adj_semi (double delta) } void -VarispeedDialog::apply_speed () +VarispeedDialog::apply_semitones () { - int cents = _semitones_spinner.get_value () * 100 + _cents_spinner.get_value (); + if (ignore_changes) { + return; + } + int cents = _semitones_spinner.get_value () * 100 + _cents_spinner.get_value (); double speed = pow (2.0, ((double)cents / 1200.0)); + { + PBD::Unwinder uw (ignore_changes, true); + _percent_adjustment.set_value (100. * pow (2.0, (cents/1200.0))); + } + + if (_session && _session->default_play_speed () != speed) { + _session->request_default_play_speed (speed); + } +} + +void +VarispeedDialog::apply_percentage () +{ + if (ignore_changes) { + return; + } + + double speed = 1.0 + (_percent_spinner.get_value() / 100.0); + + { + PBD::Unwinder uw (ignore_changes, true); + double absspeed = ::abs (speed); + double semitones = 12. * (log (absspeed - 1.0) / log(2.)); + _semitones_adjustment.set_value (floor (semitones)); + _cents_adjustment.set_value (100. * fmod (semitones, 1.)); + } + if (_session && _session->default_play_speed () != speed) { _session->request_default_play_speed (speed); } @@ -93,7 +135,7 @@ VarispeedDialog::apply_speed () void VarispeedDialog::on_show () { - apply_speed (); + apply_semitones (); ArdourDialog::on_show (); set_position (Gtk::WIN_POS_NONE); // remember position from now on } diff --git a/gtk2_ardour/varispeed_dialog.h b/gtk2_ardour/varispeed_dialog.h index 094075030f..e6c0b08854 100644 --- a/gtk2_ardour/varispeed_dialog.h +++ b/gtk2_ardour/varispeed_dialog.h @@ -34,7 +34,8 @@ public: void adj_semi (double delta); private: - void apply_speed (); + void apply_semitones (); + void apply_percentage (); void on_show (); void on_hide (); @@ -42,8 +43,12 @@ private: Gtk::Adjustment _semitones_adjustment; Gtk::Adjustment _cents_adjustment; + Gtk::Adjustment _percent_adjustment; Gtk::SpinButton _semitones_spinner; Gtk::SpinButton _cents_spinner; + Gtk::SpinButton _percent_spinner; + + bool ignore_changes; }; #endif