timestretching: fix inaccuracies in generated length
The design ignored the ratio computed by the drag interaction, and relied on getting the stretch ratio from the dialog. This truncated the actual ratio, leading to (relatively) small errors in the length of the generated region. Now, if the ratio provided by the drag is not (1/1) (i.e. a single click while in timefx mode) then the percentage stretch spinner is marked insensitive and the stretch ratio is taken from the given ratio. For single clicks, the user can still adjust the percentage as they wish
This commit is contained in:
parent
2d24bcdf4a
commit
b806ccf373
@ -5517,9 +5517,22 @@ TimeFXDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||
parameters for the timestretch.
|
||||
*/
|
||||
|
||||
ratio_t ratio (1, 1);
|
||||
if (_editor->get_selection().regions.empty()) {
|
||||
_primary->get_time_axis_view().hide_timestretch ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (movement_occurred) {
|
||||
if (!movement_occurred) {
|
||||
_primary->get_time_axis_view().hide_timestretch ();
|
||||
|
||||
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);
|
||||
|
||||
@ -5547,9 +5560,7 @@ TimeFXDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||
ratio = ((newlen - _primary->region()->length()) / newlen) * 100;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
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
|
||||
@ -5559,7 +5570,6 @@ TimeFXDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||
if (_editor->time_stretch (_editor->get_selection().regions, ratio) == -1) {
|
||||
error << _("An error occurred while executing time stretch operation") << endmsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -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 ()) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user