When sounding notes on selection / note movements, play the note for as long as the...
authorCarl Hetherington <carl@carlh.net>
Fri, 8 Jun 2012 13:21:05 +0000 (13:21 +0000)
committerCarl Hetherington <carl@carlh.net>
Fri, 8 Jun 2012 13:21:05 +0000 (13:21 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@12606 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/canvas-note.cc
gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_region_view.h
gtk2_ardour/note_player.cc
gtk2_ardour/note_player.h

index f6497776a5063498271c92919383319c03bb1440..b98cbab5ff02172ed8e8905b88131e1e42cf0ccd 100644 (file)
@@ -22,11 +22,17 @@ CanvasNote::CanvasNote (MidiRegionView&                   region,
 bool
 CanvasNote::on_event(GdkEvent* ev)
 {
+       bool r = true;
+
        if (!CanvasNoteEvent::on_event (ev)) {
-               return _region.get_time_axis_view().editor().canvas_note_event (ev, this);
+               r = _region.get_time_axis_view().editor().canvas_note_event (ev, this);
        }
 
-       return true;
+       if (ev->type == GDK_BUTTON_RELEASE) {
+               _region.note_button_release ();
+       }
+       
+       return r;
 }
 
 void
index 25ef2dfc339d1e95fa16feb9f1cd1db6be6f84f1..70f080720dba2c691642fcbfa4b199b4380926ce 100644 (file)
@@ -110,6 +110,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
        , _last_event_y (0)
        , pre_enter_cursor (0)
        , pre_press_cursor (0)
+       , _note_player (0)
 {
        _note_group->raise_to_top();
        PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
@@ -150,6 +151,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
        , _last_event_y (0)
        , pre_enter_cursor (0)
        , pre_press_cursor (0)
+       , _note_player (0)
 {
        _note_group->raise_to_top();
        PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
@@ -198,6 +200,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other)
        , _last_event_y (0)
        , pre_enter_cursor (0)
        , pre_press_cursor (0)
+       , _note_player (0)
 {
        Gdk::Color c;
        int r,g,b,a;
@@ -232,6 +235,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<M
        , _last_event_y (0)
        , pre_enter_cursor (0)
        , pre_press_cursor (0)
+       , _note_player (0)
 {
        Gdk::Color c;
        int r,g,b,a;
@@ -318,6 +322,8 @@ MidiRegionView::connect_to_diskstream ()
 bool
 MidiRegionView::canvas_event(GdkEvent* ev)
 {
+       bool r;
+       
        switch (ev->type) {
        case GDK_ENTER_NOTIFY:
        case GDK_LEAVE_NOTIFY:
@@ -357,7 +363,10 @@ MidiRegionView::canvas_event(GdkEvent* ev)
                return button_press (&ev->button);
 
        case GDK_BUTTON_RELEASE:
-               return button_release (&ev->button);
+               r = button_release (&ev->button);
+               delete _note_player;
+               _note_player = 0;
+               return r;
 
        case GDK_ENTER_NOTIFY:
                return enter_notify (&ev->crossing);
@@ -1539,13 +1548,15 @@ MidiRegionView::play_midi_note(boost::shared_ptr<NoteType> note)
                return;
        }
 
-       NotePlayer* np = new NotePlayer (route_ui->midi_track());
+       NotePlayer* np = new NotePlayer (route_ui->midi_track ());
        np->add (note);
        np->play ();
+
+       /* NotePlayer deletes itself */
 }
 
 void
-MidiRegionView::play_midi_chord (vector<boost::shared_ptr<NoteType> > notes)
+MidiRegionView::start_playing_midi_note(boost::shared_ptr<NoteType> note)
 {
        if (_no_sound_notes || !Config->get_sound_midi_notes()) {
                return;
@@ -1557,13 +1568,33 @@ MidiRegionView::play_midi_chord (vector<boost::shared_ptr<NoteType> > notes)
                return;
        }
 
-       NotePlayer* np = new NotePlayer (route_ui->midi_track());
+       delete _note_player;
+       _note_player = new NotePlayer (route_ui->midi_track ());
+       _note_player->add (note);
+       _note_player->on ();
+}
+
+void
+MidiRegionView::start_playing_midi_chord (vector<boost::shared_ptr<NoteType> > notes)
+{
+       if (_no_sound_notes || !Config->get_sound_midi_notes()) {
+               return;
+       }
+
+       RouteUI* route_ui = dynamic_cast<RouteUI*> (&trackview);
+
+       if (!route_ui || !route_ui->midi_track()) {
+               return;
+       }
+
+       delete _note_player;
+       _note_player = new NotePlayer (route_ui->midi_track());
 
        for (vector<boost::shared_ptr<NoteType> >::iterator n = notes.begin(); n != notes.end(); ++n) {
-               np->add (*n);
+               _note_player->add (*n);
        }
 
-       np->play ();
+       _note_player->on ();
 }
 
 
@@ -2338,7 +2369,7 @@ MidiRegionView::add_to_selection (CanvasNoteEvent* ev)
 
        if (_selection.insert (ev).second) {
                ev->set_selected (true);
-               play_midi_note ((ev)->note());
+               start_playing_midi_note ((ev)->note());
        }
 
        if (add_mrv_selection) {
@@ -2379,13 +2410,13 @@ MidiRegionView::move_selection(double dx, double dy, double cumulative_dy)
                                shifted.push_back (moved_note);
                        }
 
-                       play_midi_chord (shifted);
+                       start_playing_midi_chord (shifted);
 
                } else if (!to_play.empty()) {
 
                        boost::shared_ptr<NoteType> moved_note (new NoteType (*to_play.front()));
                        moved_note->set_note (moved_note->note() + cumulative_dy);
-                       play_midi_note (moved_note);
+                       start_playing_midi_note (moved_note);
                }
        }
 }
@@ -3794,3 +3825,10 @@ MidiRegionView::selection_cleared (MidiRegionView* rv)
        /* Clear our selection in sympathy; but don't signal the fact */
        clear_selection (false);
 }
+
+void
+MidiRegionView::note_button_release ()
+{
+       delete _note_player;
+       _note_player = 0;
+}
index 8ad1214c78c8eae3fd2fc6b282477db6011f60c2..0663e75a7b4fc5ce3ac5a261ac77b42f0facdd0e 100644 (file)
@@ -64,6 +64,7 @@ class AutomationRegionView;
 class MidiCutBuffer;
 class MidiListEditor;
 class EditNoteDialog;
+class NotePlayer;
 
 class MidiRegionView : public RegionView
 {
@@ -232,6 +233,8 @@ public:
 
        MouseState mouse_state() const { return _mouse_state; }
 
+       void note_button_release ();
+
        struct NoteResizeData {
                ArdourCanvas::CanvasNote  *canvas_note;
                ArdourCanvas::SimpleRect  *resize_rect;
@@ -338,8 +341,9 @@ private:
        /** Play the NoteOn event of the given note immediately
         * and schedule the playback of the corresponding NoteOff event.
         */
-       void play_midi_note(boost::shared_ptr<NoteType> note);
-       void play_midi_chord (std::vector<boost::shared_ptr<NoteType> > notes);
+       void play_midi_note (boost::shared_ptr<NoteType> note);
+       void start_playing_midi_note (boost::shared_ptr<NoteType> note);
+       void start_playing_midi_chord (std::vector<boost::shared_ptr<NoteType> > notes);
 
        void clear_events();
 
@@ -473,6 +477,8 @@ private:
 
        Gdk::Cursor* pre_enter_cursor;
        Gdk::Cursor* pre_press_cursor;
+
+       NotePlayer* _note_player;
 };
 
 
index b9f480a6be41b10c3a7a912b6388322f7ba32e7a..cd5c058209b76181fe063af8fff5e2ec158f02cc 100644 (file)
@@ -31,6 +31,11 @@ NotePlayer::NotePlayer (boost::shared_ptr<MidiTrack> mt)
 {
 }
 
+NotePlayer::~NotePlayer ()
+{
+       clear ();
+}
+
 void
 NotePlayer::add (boost::shared_ptr<NoteType> note)
 {
@@ -45,11 +50,17 @@ NotePlayer::clear ()
 }
 
 void
-NotePlayer::play ()
+NotePlayer::on ()
 {
        for (Notes::iterator n = notes.begin(); n != notes.end(); ++n) {
                track->write_immediate_event ((*n)->on_event().size(), (*n)->on_event().buffer());
        }
+}
+
+void
+NotePlayer::play ()
+{
+       on ();
 
        /* note: if there is more than 1 note, we will silence them all at the same time
         */
index c39d352dd6aa350d5068d9f42e5d296f2009e309..4a1df8c31986c20ed814fbecbbb7d06c9cd27b22 100644 (file)
@@ -34,10 +34,11 @@ public:
        typedef Evoral::Note<Evoral::MusicalTime> NoteType;
 
        NotePlayer (boost::shared_ptr<ARDOUR::MidiTrack>);
-       ~NotePlayer () {}
+       ~NotePlayer ();
 
        void add (boost::shared_ptr<NoteType>);
        void play ();
+       void on ();
        void off ();
        void clear ();