Fix audible note select:

- Don't play note a bajillion times when touch selecting
	- Don't spawn a thread for each note off (schedule an idle handler instead)
	- Play notes when rect selecting


git-svn-id: svn://localhost/ardour2/branches/3.0@4392 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2009-01-07 02:40:13 +00:00
parent 37bfa28cad
commit 3f662b9f9d
4 changed files with 21 additions and 18 deletions

View File

@ -1756,7 +1756,7 @@ public:
GroupedButtons *midi_tool_button_set;
void midi_edit_mode_toggled (Editing::MidiEditMode m);
void midi_panic_button_pressed ();
bool is_midi_sound_notes_active () const { return midi_sound_notes.get_active(); }
bool sound_notes () const { return midi_sound_notes.get_active(); }
bool ignore_midi_edit_mode_toggle;

View File

@ -890,31 +890,30 @@ MidiRegionView::extend_active_notes()
void
MidiRegionView::play_midi_note(boost::shared_ptr<Evoral::Note> note)
{
if (!trackview.editor().is_midi_sound_notes_active()) {
cerr << "not_active " << endl;
if (!trackview.editor().sound_notes()) {
return;
}
RouteUI* route_ui = dynamic_cast<RouteUI*> (&trackview);
assert(route_ui);
route_ui->midi_track()->write_immediate_event(note->on_event().size(), note->on_event().buffer());
Glib::Thread::create(bind(mem_fun(this, &MidiRegionView::play_midi_note_off), note), false);
nframes_t note_length_ms = (note->off_event().time() - note->on_event().time())
* (1000 / (double)route_ui->session().nominal_frame_rate());
Glib::signal_timeout().connect(bind(mem_fun(this, &MidiRegionView::play_midi_note_off), note),
note_length_ms, G_PRIORITY_DEFAULT);
}
void
bool
MidiRegionView::play_midi_note_off(boost::shared_ptr<Evoral::Note> note)
{
RouteUI* route_ui = dynamic_cast<RouteUI*> (&trackview);
assert(route_ui);
Glib::usleep(
(note->off_event().time() - note->on_event().time()) *
(1000000 / route_ui->session().nominal_frame_rate())
);
route_ui->midi_track()->write_immediate_event(note->off_event().size(), note->off_event().buffer());
return false;
}
@ -1210,8 +1209,9 @@ MidiRegionView::note_selected(ArdourCanvas::CanvasNoteEvent* ev, bool add)
clear_selection_except(ev);
}
_selection.insert(ev);
play_midi_note(ev->note());
if (_selection.insert(ev).second) {
play_midi_note(ev->note());
}
if ( ! ev->selected()) {
ev->selected(true);
@ -1260,6 +1260,7 @@ MidiRegionView::update_drag_selection(double x1, double x2, double y1, double y2
if (!(*i)->selected()) {
(*i)->selected(true);
_selection.insert(*i);
play_midi_note((*i)->note());
}
// Not inside rectangle
} else if ((*i)->selected()) {
@ -1279,6 +1280,7 @@ MidiRegionView::update_drag_selection(double x1, double x2, double y1, double y2
if (!(*i)->selected()) {
(*i)->selected(true);
_selection.insert(*i);
play_midi_note((*i)->note());
}
// Not inside rectangle
} else if ((*i)->selected()) {

View File

@ -261,14 +261,15 @@ class MidiRegionView : public RegionView
void reset_width_dependent_items (double pixel_width);
private:
/** play back the given MIDI note immediately
/** 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<Evoral::Note> note);
/** play back the NoteOff-Event of the given note (used by
* @ref play_midi_note() ) after waiting the duration of the MIDI Note
/** Play the NoteOff-Event of the given note immediately
* (scheduled by @ref play_midi_note()).
*/
void play_midi_note_off(boost::shared_ptr<Evoral::Note> note);
bool play_midi_note_off(boost::shared_ptr<Evoral::Note> note);
void clear_events();
void switch_source(boost::shared_ptr<ARDOUR::Source> src);

View File

@ -163,7 +163,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
/** @return Sound edited notes in MIDI regions while editing
*/
virtual bool is_midi_sound_notes_active () const = 0;
virtual bool sound_notes () const = 0;
/** Possibly start the audition of a region. If \ref r is 0, or not an AudioRegion
* any current audition is cancelled. If we are currently auditioning \ref r,