13
0

When sounding notes on selection / note movements, play the note for as long as the mouse button is held down (#4574).

git-svn-id: svn://localhost/ardour2/branches/3.0@12606 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2012-06-08 13:21:05 +00:00
parent 33ffe733f1
commit fa19e1a9d0
5 changed files with 78 additions and 16 deletions

View File

@ -22,11 +22,17 @@ CanvasNote::CanvasNote (MidiRegionView& region,
bool bool
CanvasNote::on_event(GdkEvent* ev) CanvasNote::on_event(GdkEvent* ev)
{ {
bool r = true;
if (!CanvasNoteEvent::on_event (ev)) { 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 void

View File

@ -110,6 +110,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
, _last_event_y (0) , _last_event_y (0)
, pre_enter_cursor (0) , pre_enter_cursor (0)
, pre_press_cursor (0) , pre_press_cursor (0)
, _note_player (0)
{ {
_note_group->raise_to_top(); _note_group->raise_to_top();
PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys)); 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) , _last_event_y (0)
, pre_enter_cursor (0) , pre_enter_cursor (0)
, pre_press_cursor (0) , pre_press_cursor (0)
, _note_player (0)
{ {
_note_group->raise_to_top(); _note_group->raise_to_top();
PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys)); PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
@ -198,6 +200,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other)
, _last_event_y (0) , _last_event_y (0)
, pre_enter_cursor (0) , pre_enter_cursor (0)
, pre_press_cursor (0) , pre_press_cursor (0)
, _note_player (0)
{ {
Gdk::Color c; Gdk::Color c;
int r,g,b,a; int r,g,b,a;
@ -232,6 +235,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<M
, _last_event_y (0) , _last_event_y (0)
, pre_enter_cursor (0) , pre_enter_cursor (0)
, pre_press_cursor (0) , pre_press_cursor (0)
, _note_player (0)
{ {
Gdk::Color c; Gdk::Color c;
int r,g,b,a; int r,g,b,a;
@ -318,6 +322,8 @@ MidiRegionView::connect_to_diskstream ()
bool bool
MidiRegionView::canvas_event(GdkEvent* ev) MidiRegionView::canvas_event(GdkEvent* ev)
{ {
bool r;
switch (ev->type) { switch (ev->type) {
case GDK_ENTER_NOTIFY: case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY: case GDK_LEAVE_NOTIFY:
@ -357,7 +363,10 @@ MidiRegionView::canvas_event(GdkEvent* ev)
return button_press (&ev->button); return button_press (&ev->button);
case GDK_BUTTON_RELEASE: 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: case GDK_ENTER_NOTIFY:
return enter_notify (&ev->crossing); return enter_notify (&ev->crossing);
@ -1539,13 +1548,15 @@ MidiRegionView::play_midi_note(boost::shared_ptr<NoteType> note)
return; return;
} }
NotePlayer* np = new NotePlayer (route_ui->midi_track()); NotePlayer* np = new NotePlayer (route_ui->midi_track ());
np->add (note); np->add (note);
np->play (); np->play ();
/* NotePlayer deletes itself */
} }
void 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()) { if (_no_sound_notes || !Config->get_sound_midi_notes()) {
return; return;
@ -1557,13 +1568,33 @@ MidiRegionView::play_midi_chord (vector<boost::shared_ptr<NoteType> > notes)
return; 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 ();
}
for (vector<boost::shared_ptr<NoteType> >::iterator n = notes.begin(); n != notes.end(); ++n) { void
np->add (*n); MidiRegionView::start_playing_midi_chord (vector<boost::shared_ptr<NoteType> > notes)
{
if (_no_sound_notes || !Config->get_sound_midi_notes()) {
return;
} }
np->play (); 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) {
_note_player->add (*n);
}
_note_player->on ();
} }
@ -2338,7 +2369,7 @@ MidiRegionView::add_to_selection (CanvasNoteEvent* ev)
if (_selection.insert (ev).second) { if (_selection.insert (ev).second) {
ev->set_selected (true); ev->set_selected (true);
play_midi_note ((ev)->note()); start_playing_midi_note ((ev)->note());
} }
if (add_mrv_selection) { if (add_mrv_selection) {
@ -2379,13 +2410,13 @@ MidiRegionView::move_selection(double dx, double dy, double cumulative_dy)
shifted.push_back (moved_note); shifted.push_back (moved_note);
} }
play_midi_chord (shifted); start_playing_midi_chord (shifted);
} else if (!to_play.empty()) { } else if (!to_play.empty()) {
boost::shared_ptr<NoteType> moved_note (new NoteType (*to_play.front())); boost::shared_ptr<NoteType> moved_note (new NoteType (*to_play.front()));
moved_note->set_note (moved_note->note() + cumulative_dy); 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 our selection in sympathy; but don't signal the fact */
clear_selection (false); clear_selection (false);
} }
void
MidiRegionView::note_button_release ()
{
delete _note_player;
_note_player = 0;
}

View File

@ -64,6 +64,7 @@ class AutomationRegionView;
class MidiCutBuffer; class MidiCutBuffer;
class MidiListEditor; class MidiListEditor;
class EditNoteDialog; class EditNoteDialog;
class NotePlayer;
class MidiRegionView : public RegionView class MidiRegionView : public RegionView
{ {
@ -232,6 +233,8 @@ public:
MouseState mouse_state() const { return _mouse_state; } MouseState mouse_state() const { return _mouse_state; }
void note_button_release ();
struct NoteResizeData { struct NoteResizeData {
ArdourCanvas::CanvasNote *canvas_note; ArdourCanvas::CanvasNote *canvas_note;
ArdourCanvas::SimpleRect *resize_rect; ArdourCanvas::SimpleRect *resize_rect;
@ -338,8 +341,9 @@ private:
/** Play the NoteOn event of the given note immediately /** Play the NoteOn event of the given note immediately
* and schedule the playback of the corresponding NoteOff event. * and schedule the playback of the corresponding NoteOff event.
*/ */
void play_midi_note(boost::shared_ptr<NoteType> note); void play_midi_note (boost::shared_ptr<NoteType> note);
void play_midi_chord (std::vector<boost::shared_ptr<NoteType> > notes); 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(); void clear_events();
@ -473,6 +477,8 @@ private:
Gdk::Cursor* pre_enter_cursor; Gdk::Cursor* pre_enter_cursor;
Gdk::Cursor* pre_press_cursor; Gdk::Cursor* pre_press_cursor;
NotePlayer* _note_player;
}; };

View File

@ -31,6 +31,11 @@ NotePlayer::NotePlayer (boost::shared_ptr<MidiTrack> mt)
{ {
} }
NotePlayer::~NotePlayer ()
{
clear ();
}
void void
NotePlayer::add (boost::shared_ptr<NoteType> note) NotePlayer::add (boost::shared_ptr<NoteType> note)
{ {
@ -45,11 +50,17 @@ NotePlayer::clear ()
} }
void void
NotePlayer::play () NotePlayer::on ()
{ {
for (Notes::iterator n = notes.begin(); n != notes.end(); ++n) { for (Notes::iterator n = notes.begin(); n != notes.end(); ++n) {
track->write_immediate_event ((*n)->on_event().size(), (*n)->on_event().buffer()); 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 /* note: if there is more than 1 note, we will silence them all at the same time
*/ */

View File

@ -34,10 +34,11 @@ public:
typedef Evoral::Note<Evoral::MusicalTime> NoteType; typedef Evoral::Note<Evoral::MusicalTime> NoteType;
NotePlayer (boost::shared_ptr<ARDOUR::MidiTrack>); NotePlayer (boost::shared_ptr<ARDOUR::MidiTrack>);
~NotePlayer () {} ~NotePlayer ();
void add (boost::shared_ptr<NoteType>); void add (boost::shared_ptr<NoteType>);
void play (); void play ();
void on ();
void off (); void off ();
void clear (); void clear ();