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:
parent
33ffe733f1
commit
fa19e1a9d0
@ -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
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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 ();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user