diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 2711fc146c..458a92b2cd 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -5517,48 +5517,58 @@ TimeFXDrag::finished (GdkEvent* event, bool movement_occurred) parameters for the timestretch. */ - ratio_t ratio (1, 1); - - if (movement_occurred) { - - motion (event, false); - + if (_editor->get_selection().regions.empty()) { _primary->get_time_axis_view().hide_timestretch (); - - timepos_t adjusted_pos = adjusted_current_time (event); - - if (adjusted_pos < _primary->region()->position()) { - /* backwards drag of the left edge - not usable */ - return; - } - - timecnt_t newlen = _primary->region()->position().distance (adjusted_pos); - - if (_primary->region()->length().time_domain() == Temporal::BeatTime) { - ratio = ratio_t (newlen.ticks(), _primary->region()->length().ticks()); - } else { - ratio = ratio_t (newlen.samples(), _primary->region()->length().samples()); - } - -#ifndef USE_RUBBERBAND - // Soundtouch uses fraction / 100 instead of normal (/ 1) -#warning NUTEMPO timefx request now uses a rational type so this needs revisiting - if (_primary->region()->data_type() == DataType::AUDIO) { - ratio = ((newlen - _primary->region()->length()) / newlen) * 100; - } -#endif + return; } - if (!_editor->get_selection().regions.empty()) { - /* primary will already be included in the selection, and edit - group shared editing will propagate selection across - equivalent regions, so just use the current region - selection. - */ + if (!movement_occurred) { + _primary->get_time_axis_view().hide_timestretch (); - if (_editor->time_stretch (_editor->get_selection().regions, ratio) == -1) { + if (_editor->time_stretch (_editor->get_selection().regions, ratio_t (1, 1)) == -1) { error << _("An error occurred while executing time stretch operation") << endmsg; } + return; + } + + + ratio_t ratio (1, 1); + + motion (event, false); + + _primary->get_time_axis_view().hide_timestretch (); + + timepos_t adjusted_pos = adjusted_current_time (event); + + if (adjusted_pos < _primary->region()->position()) { + /* backwards drag of the left edge - not usable */ + return; + } + + timecnt_t newlen = _primary->region()->position().distance (adjusted_pos); + + if (_primary->region()->length().time_domain() == Temporal::BeatTime) { + ratio = ratio_t (newlen.ticks(), _primary->region()->length().ticks()); + } else { + ratio = ratio_t (newlen.samples(), _primary->region()->length().samples()); + } + +#ifndef USE_RUBBERBAND + // Soundtouch uses fraction / 100 instead of normal (/ 1) +#warning NUTEMPO timefx request now uses a rational type so this needs revisiting + if (_primary->region()->data_type() == DataType::AUDIO) { + ratio = ((newlen - _primary->region()->length()) / newlen) * 100; + } +#endif + + /* primary will already be included in the selection, and edit + group shared editing will propagate selection across + equivalent regions, so just use the current region + selection. + */ + + if (_editor->time_stretch (_editor->get_selection().regions, ratio) == -1) { + error << _("An error occurred while executing time stretch operation") << endmsg; } } diff --git a/gtk2_ardour/editor_timefx.cc b/gtk2_ardour/editor_timefx.cc index dfe1022c4f..8b63fd0054 100644 --- a/gtk2_ardour/editor_timefx.cc +++ b/gtk2_ardour/editor_timefx.cc @@ -172,7 +172,7 @@ Editor::time_fx (RegionList& regions, Temporal::ratio_t ratio, bool pitching) const timecnt_t newlen = regions.front()->length().scale (ratio); const timepos_t pos = regions.front()->position (); - current_timefx = new TimeFXDialog (*this, pitching, oldlen, newlen, pos); + current_timefx = new TimeFXDialog (*this, pitching, oldlen, newlen, ratio, pos); current_timefx->regions = regions; switch (current_timefx->run ()) { diff --git a/gtk2_ardour/time_fx_dialog.cc b/gtk2_ardour/time_fx_dialog.cc index 1e27f2f85f..61b62640fc 100644 --- a/gtk2_ardour/time_fx_dialog.cc +++ b/gtk2_ardour/time_fx_dialog.cc @@ -55,7 +55,7 @@ using namespace PBD; using namespace Gtk; using namespace Gtkmm2ext; -TimeFXDialog::TimeFXDialog (Editor& e, bool pitch, timecnt_t const & oldlen, timecnt_t const & new_length, timepos_t const & position) +TimeFXDialog::TimeFXDialog (Editor& e, bool pitch, timecnt_t const & oldlen, timecnt_t const & new_length, Temporal::ratio_t const & ratio, timepos_t const & position) : ArdourDialog (X_("time fx dialog")) , editor (e) , pitching (pitch) @@ -71,6 +71,7 @@ TimeFXDialog::TimeFXDialog (Editor& e, bool pitch, timecnt_t const & oldlen, tim , pitch_octave_spinner (pitch_octave_adjustment) , pitch_semitone_spinner (pitch_semitone_adjustment) , pitch_cent_spinner (pitch_cent_adjustment) + , duration_ratio (ratio) , duration_adjustment (100.0, -1000.0, 1000.0, 1.0, 10.0) , duration_clock (0) , ignore_adjustment_change (false) @@ -105,6 +106,8 @@ TimeFXDialog::TimeFXDialog (Editor& e, bool pitch, timecnt_t const & oldlen, tim upper_button_box.pack_start (*l, false, false); + /* if the ratio is already set, do not allow adjustment */ + if (pitching) { Table* table = manage (new Table (4, 3, false)); table->set_row_spacings (6); @@ -158,11 +161,15 @@ TimeFXDialog::TimeFXDialog (Editor& e, bool pitch, timecnt_t const & oldlen, tim table->attach (*clock_align, 1, 2, row, row+1, Gtk::AttachOptions (Gtk::EXPAND|Gtk::FILL), Gtk::FILL, 0, 0); row++; - const double fract = (new_length / original_length).to_double(); /* note the *100.0 to convert fract into a percentage */ - duration_adjustment.set_value (fract*100.0); + duration_adjustment.set_value (duration_ratio.to_double() * 100.0); + Gtk::SpinButton* spinner = manage (new Gtk::SpinButton (duration_adjustment, 1.0, 3)); + if (duration_ratio != Temporal::ratio_t (1, 1)) { + spinner->set_sensitive (false); + } + l = manage (new Gtk::Label (_("Percent"))); table->attach (*l, 0, 1, row, row+1, Gtk::FILL, Gtk::FILL, 0, 0); table->attach (*spinner, 1, 2, row, row+1, Gtk::FILL, Gtk::FILL, 0, 0); @@ -266,6 +273,10 @@ TimeFXDialog::get_time_fraction () const return Temporal::ratio_t (1, 1); } + if (duration_ratio != Temporal::ratio_t (1, 1)) { + return duration_ratio; + } + return Temporal::ratio_t (duration_adjustment.get_value(), 100); } diff --git a/gtk2_ardour/time_fx_dialog.h b/gtk2_ardour/time_fx_dialog.h index a31401c0fa..f4a80bd793 100644 --- a/gtk2_ardour/time_fx_dialog.h +++ b/gtk2_ardour/time_fx_dialog.h @@ -42,7 +42,7 @@ class TimeFXDialog : public ArdourDialog, public ProgressReporter { public: /* We need a position so that BBT mode in the clock can function */ - TimeFXDialog (Editor& e, bool for_pitch, Temporal::timecnt_t const & old_length, Temporal::timecnt_t const & new_length, Temporal::timepos_t const & position); + TimeFXDialog (Editor& e, bool for_pitch, Temporal::timecnt_t const & old_length, Temporal::timecnt_t const & new_length, Temporal::ratio_t const &, Temporal::timepos_t const & position); ARDOUR::TimeFXRequest request; Editor& editor; @@ -93,6 +93,7 @@ private: Gtk::SpinButton pitch_octave_spinner; Gtk::SpinButton pitch_semitone_spinner; Gtk::SpinButton pitch_cent_spinner; + Temporal::ratio_t duration_ratio; Gtk::Adjustment duration_adjustment; AudioClock* duration_clock; bool ignore_adjustment_change;