summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/canvas-note.cc10
-rw-r--r--gtk2_ardour/midi_region_view.cc56
-rw-r--r--gtk2_ardour/midi_region_view.h10
-rw-r--r--gtk2_ardour/note_player.cc13
-rw-r--r--gtk2_ardour/note_player.h3
5 files changed, 77 insertions, 15 deletions
diff --git a/gtk2_ardour/canvas-note.cc b/gtk2_ardour/canvas-note.cc
index f6497776a5..b98cbab5ff 100644
--- a/gtk2_ardour/canvas-note.cc
+++ b/gtk2_ardour/canvas-note.cc
@@ -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
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index 25ef2dfc33..70f080720d 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -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;
+}
diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h
index 8ad1214c78..0663e75a7b 100644
--- a/gtk2_ardour/midi_region_view.h
+++ b/gtk2_ardour/midi_region_view.h
@@ -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;
};
diff --git a/gtk2_ardour/note_player.cc b/gtk2_ardour/note_player.cc
index b9f480a6be..cd5c058209 100644
--- a/gtk2_ardour/note_player.cc
+++ b/gtk2_ardour/note_player.cc
@@ -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
*/
diff --git a/gtk2_ardour/note_player.h b/gtk2_ardour/note_player.h
index c39d352dd6..4a1df8c319 100644
--- a/gtk2_ardour/note_player.h
+++ b/gtk2_ardour/note_player.h
@@ -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 ();