X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fquantize.cc;h=7ede60b578540e73472f4f342819804108810a67;hb=00ddd099ed5cd6e0d77448670381d13d88b96218;hp=7aedb98a4dd7cce5eac3a3c15c58212d9b8b67be;hpb=539c8361de35364effe804e2db184790226b340a;p=ardour.git diff --git a/libs/ardour/quantize.cc b/libs/ardour/quantize.cc index 7aedb98a4d..7ede60b578 100644 --- a/libs/ardour/quantize.cc +++ b/libs/ardour/quantize.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2004 Paul Davis + Copyright (C) 2004 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,9 +40,9 @@ using namespace ARDOUR; * 0.25 = quantize to beats/4, etc. */ -Quantize::Quantize (Session& s, QuantizeType /* type */, +Quantize::Quantize (Session& s, QuantizeType /* type */, bool snap_start, bool snap_end, - double start_grid, double end_grid, + double start_grid, double end_grid, float strength, float swing, float threshold) : session (s) , _snap_start (snap_start) @@ -60,67 +60,75 @@ Quantize::~Quantize () } Command* -Quantize::operator () (boost::shared_ptr model, std::vector::Notes>& seqs) +Quantize::operator () (boost::shared_ptr model, + double position, + std::vector::Notes>& seqs) { + /* Calculate offset from start of model to next closest quantize step, + to quantize relative to actual session beats (etc.) rather than from the + start of the model. + */ + const double round_pos = ceil(position / _start_grid) * _start_grid; + const double offset = round_pos - position; + bool even; - MidiModel::DiffCommand* cmd = new MidiModel::DiffCommand (model, "quantize"); + MidiModel::NoteDiffCommand* cmd = new MidiModel::NoteDiffCommand (model, "quantize"); for (std::vector::Notes>::iterator s = seqs.begin(); s != seqs.end(); ++s) { even = false; for (Evoral::Sequence::Notes::iterator i = (*s).begin(); i != (*s).end(); ++i) { - - double new_start = round ((*i)->time() / _start_grid) * _start_grid; - double new_end = round ((*i)->end_time() / _end_grid) * _end_grid; - double delta; - + + double new_start = round ((*i)->time() / _start_grid) * _start_grid + offset; + double new_end = round ((*i)->end_time() / _end_grid) * _end_grid + offset; + if (_swing > 0.0 && !even) { - + double next_grid = new_start + _start_grid; - + /* find a spot 2/3 (* swing factor) of the way between the grid point we would put this note at, and the nominal position of the next note. */ - + new_start = new_start + (2.0/3.0 * _swing * (next_grid - new_start)); - + } else if (_swing < 0.0 && !even) { - + double prev_grid = new_start - _start_grid; - + /* find a spot 2/3 (* swing factor) of the way between the grid point we would put this note at, and the nominal position of the previous note. */ - + new_start = new_start - (2.0/3.0 * _swing * (new_start - prev_grid)); - + } - - delta = new_start - (*i)->time(); - + + double delta = new_start - (*i)->time(); + if (fabs (delta) >= _threshold) { if (_snap_start) { delta *= _strength; - cmd->change ((*i), MidiModel::DiffCommand::StartTime, + cmd->change ((*i), MidiModel::NoteDiffCommand::StartTime, (*i)->time() + delta); } } - + if (_snap_end) { delta = new_end - (*i)->end_time(); - + if (fabs (delta) >= _threshold) { double new_dur = new_end - new_start; - + if (new_dur == 0.0) { new_dur = _end_grid; } - - cmd->change ((*i), MidiModel::DiffCommand::Length, new_dur); + + cmd->change ((*i), MidiModel::NoteDiffCommand::Length, new_dur); } } - + even = !even; } }