use diff commands for quantize, with infrastructure changes as required
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 7 Sep 2009 16:53:53 +0000 (16:53 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 7 Sep 2009 16:53:53 +0000 (16:53 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@5639 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/editor.h
gtk2_ardour/editor_ops.cc
gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_region_view.h
libs/ardour/ardour/midi_operator.h
libs/ardour/ardour/quantize.h
libs/ardour/quantize.cc

index ad7c54752bbfdbf18a4605fa19e2f581eb399685..5313c59c6d70e2e538e05a8503fa80f7fc4cba01 100644 (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 */
index feeae881f04149c5337c66f42976b6c03bb47553..d27727348d9b2397e253e552421fa71a89beb268 100644 (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
index f87cc50d4ede264ef6c44182423a0782ee398b2e..138b53b316d0cd77dd84562260b8251bd791981e 100644 (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 ();
-}
 
index c855dfeb0f0ae85323784cb0c88036ad88e8d230..5a7955e1405d34afca3980603ae11accbdde47df 100644 (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
index e3ed6aabfd18b57cb0c2e2f6759d4429725b8203..64ceaad841f1ad107a16b3ee5ada61f94902fc6a 100644 (file)
 #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;
 };
 
index 57e54672941d64363bbad1ff5e9a0ec21d7cefd4..8db7e4185f2b80f2896a5d9075b98d5cf2c87031 100644 (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:
index becb3bd491a224f75579ad97552e53aead5a5dde..7aedb98a4dd7cce5eac3a3c15c58212d9b8b67be 100644 (file)
 #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;
 }