use diff commands for quantize, with infrastructure changes as required

git-svn-id: svn://localhost/ardour2/branches/3.0@5639 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2009-09-07 16:53:53 +00:00
parent 79dc191d6b
commit 539c8361de
7 changed files with 61 additions and 110 deletions

View File

@ -1920,7 +1920,7 @@ public:
void apply_filter (ARDOUR::Filter&, std::string cmd);
void apply_midi_note_edit_op_to_region (ARDOUR::MidiOperator& op, MidiRegionView& mrv);
Command* apply_midi_note_edit_op_to_region (ARDOUR::MidiOperator& op, MidiRegionView& mrv);
void apply_midi_note_edit_op (ARDOUR::MidiOperator& op);
/* handling cleanup */

View File

@ -4809,23 +4809,23 @@ Editor::strip_region_silence ()
}
}
void
Command*
Editor::apply_midi_note_edit_op_to_region (MidiOperator& op, MidiRegionView& mrv)
{
vector<Evoral::Sequence<Evoral::MusicalTime>::Notes> v;
Evoral::Sequence<Evoral::MusicalTime>::Notes selected;
mrv.selection_as_notelist (selected);
vector<Evoral::Sequence<Evoral::MusicalTime>::Notes> v;
v.push_back (selected);
mrv.selection_as_notelist (v.front());
op (v);
mrv.replace_selected (v.front());
return op (mrv.midi_region()->model(), v);
}
void
Editor::apply_midi_note_edit_op (MidiOperator& op)
{
RegionSelection rs;
Command* cmd;
get_regions_for_action (rs);
@ -4842,7 +4842,11 @@ Editor::apply_midi_note_edit_op (MidiOperator& op)
MidiRegionView* const mrv = dynamic_cast<MidiRegionView*> (*r);
if (mrv) {
apply_midi_note_edit_op_to_region (op, *mrv);
cmd = apply_midi_note_edit_op_to_region (op, *mrv);
if (cmd) {
(*cmd)();
session->add_command (cmd);
}
}
r = tmp;
@ -6585,10 +6589,8 @@ Editor::goto_visual_state (uint32_t n)
void
Editor::start_visual_state_op (uint32_t n)
{
cerr << "Start visual op\n";
if (visual_state_op_connection.empty()) {
visual_state_op_connection = Glib::signal_timeout().connect (bind (mem_fun (*this, &Editor::end_visual_state_op), n), 1000);
cerr << "\tqueued new timeout\n";
}
}
@ -6596,12 +6598,9 @@ void
Editor::cancel_visual_state_op (uint32_t n)
{
if (!visual_state_op_connection.empty()) {
cerr << "cancel visual op, time to goto\n";
visual_state_op_connection.disconnect();
goto_visual_state (n);
} else {
cerr << "cancel visual op, do nothing\n";
}
}
}
bool

View File

@ -1573,19 +1573,20 @@ MidiRegionView::note_dropped(CanvasNoteEvent* ev, double dt, uint8_t dnote)
highest_note_difference = highest_note_in_selection - 127;
}
start_delta_command(_("move notes"));
start_diff_command(_("move notes"));
for (Selection::iterator i = _selection.begin(); i != _selection.end() ; ) {
Selection::iterator next = i;
++next;
const boost::shared_ptr<NoteType> copy(new NoteType(*(*i)->note().get()));
for (Selection::iterator i = _selection.begin(); i != _selection.end() ; ++i) {
nframes64_t start_frames = beats_to_frames((*i)->note()->time());
cerr << "starting at " << (*i)->note()->time()
<< " (" << start_frames << ") delta on drag = " << dt << endl;
/* XXX THERE IS SOMETHING WRONG HERE THAT IS RELATED TO USING DT AND NOT
SOMETHING RELATED TO REGION START + DT ... XXXX
*/
if (dt >= 0) {
cerr << "Motion was " << snap_frame_to_frame(trackview.editor().pixel_to_frame(dt)) << endl;
start_frames += snap_frame_to_frame(trackview.editor().pixel_to_frame(dt));
@ -1601,13 +1602,10 @@ MidiRegionView::note_dropped(CanvasNoteEvent* ev, double dt, uint8_t dnote)
Evoral::MusicalTime new_time = frames_to_beats(start_frames);
if (new_time < 0) {
i = next;
continue;
}
copy->set_time (new_time);
cerr << "copy time = " << copy->time() << endl;
diff_add_change (*i, MidiModel::DiffCommand::StartTime, new_time);
uint8_t original_pitch = (*i)->note()->note();
uint8_t new_pitch = original_pitch + dnote - highest_note_difference;
@ -1624,16 +1622,10 @@ MidiRegionView::note_dropped(CanvasNoteEvent* ev, double dt, uint8_t dnote)
lowest_note_in_selection = std::min(lowest_note_in_selection, new_pitch);
highest_note_in_selection = std::max(highest_note_in_selection, new_pitch);
copy->set_note(new_pitch);
delta_remove_note(*i);
cerr << "Adding note: " << *copy << endl;
delta_add_note(copy, (*i)->selected());
i = next;
diff_add_change (*i, MidiModel::DiffCommand::NoteNumber, new_pitch);
}
apply_delta();
apply_diff();
// care about notes being moved beyond the upper/lower bounds on the canvas
if (lowest_note_in_selection < midi_stream_view()->lowest_note() ||
@ -1810,18 +1802,16 @@ MidiRegionView::commit_resizing(CanvasNote::NoteEnd note_end, double event_x, bo
void
MidiRegionView::change_note_velocity(CanvasNoteEvent* event, int8_t velocity, bool relative)
{
const boost::shared_ptr<NoteType> copy(new NoteType(*(event->note().get())));
uint8_t new_velocity;
if (relative) {
uint8_t new_velocity = copy->velocity() + velocity;
new_velocity = event->note()->velocity() + velocity;
clamp_to_0_127(new_velocity);
copy->set_velocity(new_velocity);
} else {
copy->set_velocity(velocity);
new_velocity = velocity;
}
delta_remove_note(event);
delta_add_note(copy, event->selected(), true);
diff_add_change (event, MidiModel::DiffCommand::Velocity, new_velocity);
}
void
@ -1916,24 +1906,23 @@ MidiRegionView::trim_note (CanvasNoteEvent* event, Evoral::MusicalTime front_del
void
MidiRegionView::change_note_time (CanvasNoteEvent* event, Evoral::MusicalTime delta, bool relative)
{
const boost::shared_ptr<NoteType> copy(new NoteType(*(event->note().get())));
Evoral::MusicalTime new_time;
if (relative) {
if (delta < 0.0) {
if (copy->time() < -delta) {
copy->set_time (0);
if (event->note()->time() < -delta) {
new_time = 0;
} else {
copy->set_time (copy->time() + delta);
new_time = event->note()->time() + delta;
}
} else {
copy->set_time (copy->time() + delta);
new_time = event->note()->time() + delta;
}
} else {
copy->set_time (delta);
new_time = delta;
}
delta_remove_note(event);
delta_add_note(copy, event->selected(), false);
diff_add_change (event, MidiModel::DiffCommand::StartTime, new_time);
}
void
@ -1963,7 +1952,7 @@ MidiRegionView::change_velocities (bool up, bool fine, bool allow_smush)
}
}
start_delta_command(_("change velocities"));
start_diff_command(_("change velocities"));
for (Selection::iterator i = _selection.begin(); i != _selection.end();) {
Selection::iterator next = i;
@ -1972,7 +1961,7 @@ MidiRegionView::change_velocities (bool up, bool fine, bool allow_smush)
i = next;
}
apply_delta();
apply_diff();
}
@ -2107,7 +2096,7 @@ MidiRegionView::nudge_notes (bool forward)
delta = -delta;
}
start_delta_command (_("nudge"));
start_diff_command (_("nudge"));
for (Selection::iterator i = _selection.begin(); i != _selection.end(); ) {
Selection::iterator next = i;
@ -2116,30 +2105,17 @@ MidiRegionView::nudge_notes (bool forward)
i = next;
}
apply_delta ();
apply_diff ();
}
void
MidiRegionView::change_channel(uint8_t channel)
{
start_delta_command(_("change channel"));
for (Selection::iterator i = _selection.begin(); i != _selection.end();) {
Selection::iterator next = i;
++next;
CanvasNoteEvent* event = *i;
const boost::shared_ptr<NoteType> copy(new NoteType(*(event->note().get())));
copy->set_channel(channel);
delta_remove_note(event);
delta_add_note(copy, event->selected());
i = next;
start_diff_command(_("change channel"));
for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
diff_add_change (*i, MidiModel::DiffCommand::Channel, channel);
}
apply_delta();
apply_diff();
}
@ -2400,35 +2376,9 @@ MidiRegionView::selection_as_notelist (NoteList& selected)
{
for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
if ((*i)->selected()) {
/* make a copy of the original */
selected.push_back (boost::shared_ptr<Evoral::Note<Evoral::MusicalTime> >
(new Evoral::Note<Evoral::MusicalTime> (*((*i)->note()))));
selected.push_back ((*i)->note());
}
}
}
void
MidiRegionView::replace_selected (NoteList& replacements)
{
start_delta_command ("whatever");
for (Selection::iterator i = _selection.begin(); i != _selection.end(); ) {
Selection::iterator tmp;
tmp = i;
++tmp;
delta_remove_note (*i);
remove_from_selection (*i);
i = tmp;
}
_selection.clear ();
for (NoteList::iterator i = replacements.begin(); i != replacements.end(); ++i) {
delta_add_note (*i, true, false);
}
apply_delta_as_subcommand ();
}

View File

@ -271,9 +271,6 @@ class MidiRegionView : public RegionView
/** Convert a timestamp in frames to beats (both relative to region start) */
double frames_to_beats(nframes64_t beats) const;
/** Return the current selection as a MidiModel or null if there is no selection */
ARDOUR::MidiModel* selection_as_model () const;
void goto_previous_note ();
void goto_next_note ();
void change_note_lengths (bool, bool, bool start, bool end);
@ -284,7 +281,6 @@ class MidiRegionView : public RegionView
void show_list_editor ();
void selection_as_notelist (NoteList& selected);
void replace_selected (NoteList& replacements);
protected:
/** Allows derived types to specify their visibility requirements

View File

@ -26,14 +26,18 @@
#include "evoral/types.hpp"
#include "evoral/Sequence.hpp"
class Command;
namespace ARDOUR {
class MidiModel;
class MidiOperator {
public:
MidiOperator() {}
MidiOperator () {}
virtual ~MidiOperator() {}
virtual int operator() (std::vector<Evoral::Sequence<Evoral::MusicalTime>::Notes>&) = 0;
virtual Command* operator() (boost::shared_ptr<ARDOUR::MidiModel>, std::vector<Evoral::Sequence<Evoral::MusicalTime>::Notes>&) = 0;
virtual std::string name() const = 0;
};

View File

@ -36,7 +36,7 @@ public:
float strength, float swing, float threshold);
~Quantize ();
int operator() (std::vector<Evoral::Sequence<Evoral::MusicalTime>::Notes>&);
Command* operator() (boost::shared_ptr<ARDOUR::MidiModel>, std::vector<Evoral::Sequence<Evoral::MusicalTime>::Notes>&);
std::string name() const { return std::string ("quantize"); }
private:

View File

@ -24,12 +24,14 @@
#include "ardour/quantize.h"
#include "ardour/session.h"
#include "ardour/smf_source.h"
#include "ardour/midi_model.h"
#include "ardour/midi_region.h"
#include "ardour/tempo.h"
#include "i18n.h"
using namespace std;
using namespace PBD;
using namespace ARDOUR;
/** Quantize notes
@ -57,18 +59,17 @@ Quantize::~Quantize ()
{
}
int
Quantize::operator () (std::vector<Evoral::Sequence<Evoral::MusicalTime>::Notes>& seqs)
Command*
Quantize::operator () (boost::shared_ptr<MidiModel> model, std::vector<Evoral::Sequence<Evoral::MusicalTime>::Notes>& seqs)
{
bool even;
MidiModel::DiffCommand* cmd = new MidiModel::DiffCommand (model, "quantize");
for (std::vector<Evoral::Sequence<Evoral::MusicalTime>::Notes>::iterator s = seqs.begin();
s != seqs.end(); ++s) {
for (std::vector<Evoral::Sequence<Evoral::MusicalTime>::Notes>::iterator s = seqs.begin(); s != seqs.end(); ++s) {
even = false;
for (Evoral::Sequence<MidiModel::TimeType>::Notes::iterator i = (*s).begin();
i != (*s).end(); ++i) {
for (Evoral::Sequence<MidiModel::TimeType>::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;
@ -101,7 +102,8 @@ Quantize::operator () (std::vector<Evoral::Sequence<Evoral::MusicalTime>::Notes>
if (fabs (delta) >= _threshold) {
if (_snap_start) {
delta *= _strength;
(*i)->set_time ((*i)->time() + delta);
cmd->change ((*i), MidiModel::DiffCommand::StartTime,
(*i)->time() + delta);
}
}
@ -115,7 +117,7 @@ Quantize::operator () (std::vector<Evoral::Sequence<Evoral::MusicalTime>::Notes>
new_dur = _end_grid;
}
(*i)->set_length (new_dur);
cmd->change ((*i), MidiModel::DiffCommand::Length, new_dur);
}
}
@ -123,5 +125,5 @@ Quantize::operator () (std::vector<Evoral::Sequence<Evoral::MusicalTime>::Notes>
}
}
return 0;
return cmd;
}