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:
parent
79dc191d6b
commit
539c8361de
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user