From 5558b3cf06b98060438d1e68c8d5d2f4a9c2f8f6 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 26 Dec 2011 17:01:31 +0000 Subject: [PATCH] a grab bag of changes correcting and improving the way MIDI note on/off tracking is done. may/should fix a number of problem with spurious note-offs under a variety of circumstances git-svn-id: svn://localhost/ardour2/branches/3.0@11074 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/midi_diskstream.h | 2 + libs/ardour/ardour/midi_ring_buffer.h | 2 + libs/ardour/ardour/midi_track.h | 2 + libs/ardour/ardour/plugin.h | 4 + libs/ardour/ardour/plugin_insert.h | 2 + libs/ardour/ardour/processor.h | 7 ++ libs/ardour/midi_diskstream.cc | 26 +++-- libs/ardour/midi_playlist.cc | 147 ++++++++++++++------------ libs/ardour/midi_ring_buffer.cc | 7 ++ libs/ardour/midi_state_tracker.cc | 35 ++++-- libs/ardour/midi_track.cc | 18 +++- libs/ardour/plugin.cc | 27 ++++- libs/ardour/plugin_insert.cc | 16 +++ libs/ardour/track.cc | 5 + 14 files changed, 214 insertions(+), 86 deletions(-) diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h index 94eb56d9b5..23ae7addb0 100644 --- a/libs/ardour/ardour/midi_diskstream.h +++ b/libs/ardour/ardour/midi_diskstream.h @@ -65,6 +65,8 @@ class MidiDiskstream : public Diskstream void get_playback (MidiBuffer& dst, framecnt_t); void set_record_enabled (bool yn); + + void reset_tracker (); boost::shared_ptr midi_playlist () { return boost::dynamic_pointer_cast(_playlist); } diff --git a/libs/ardour/ardour/midi_ring_buffer.h b/libs/ardour/ardour/midi_ring_buffer.h index 14934456e1..4b352b3c4d 100644 --- a/libs/ardour/ardour/midi_ring_buffer.h +++ b/libs/ardour/ardour/midi_ring_buffer.h @@ -75,6 +75,8 @@ public: return g_atomic_int_get(&_channel_mask) & 0x0000FFFF; } + void reset_tracker (); + protected: inline bool is_channel_event(uint8_t event_type_byte) { // mask out channel information diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index 86eb8fd680..6ca48573d5 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -107,6 +107,8 @@ public: PBD::Signal1 > DataRecorded; boost::shared_ptr get_gui_feed_buffer () const; + void set_monitoring (MonitorChoice); + void set_input_active (bool); bool input_active () const; PBD::Signal0 InputActiveChanged; diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index 9c073d4a19..0c2bcbdd93 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -141,6 +141,8 @@ class Plugin : public PBD::StatefulDestructible, public Latent } void realtime_handle_transport_stopped (); + void realtime_locate (); + void monitoring_changed (); struct PresetRecord { PresetRecord () : user (true) {} @@ -257,6 +259,8 @@ private: bool _have_pending_stop_events; PresetRecord _last_preset; bool _parameter_changed_since_last_preset; + + void resolve_midi (); }; PluginPtr find_plugin(ARDOUR::Session&, std::string unique_id, ARDOUR::PluginType); diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index b7a89b663f..48ce925d3f 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -77,6 +77,8 @@ class PluginInsert : public Processor bool is_midi_instrument() const; void realtime_handle_transport_stopped (); + void realtime_locate (); + void monitoring_changed (); struct PluginControl : public AutomationControl { diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h index 08fd3ecd8d..fe23d6fdde 100644 --- a/libs/ardour/ardour/processor.h +++ b/libs/ardour/ardour/processor.h @@ -87,6 +87,13 @@ class Processor : public SessionObject, public Automatable, public Latent virtual void realtime_handle_transport_stopped () {} virtual void realtime_locate () {} + /* most processors won't care about this, but plugins that + receive MIDI or similar data from an input source that + may suddenly go "quiet" because of monitoring changes + need to know about it. + */ + virtual void monitoring_changed() {} + /* note: derived classes should implement state(), NOT get_state(), to allow us to merge C++ inheritance and XML lack-of-inheritance reasonably smoothly. diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index c1d391fa4a..e3d7014457 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -737,16 +737,16 @@ MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed) start = loop_start + ((start - loop_start) % loop_length); //cerr << "to " << start << endl; } - //cerr << "start is " << start << " loopstart: " << loop_start << " loopend: " << loop_end << endl; + // cerr << "start is " << start << " loopstart: " << loop_start << " loopend: " << loop_end << endl; } while (dur) { /* take any loop into account. we can't read past the end of the loop. */ - if (loc && (loop_end - start < dur)) { + if (loc && (loop_end - start <= dur)) { this_read = loop_end - start; - //cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl; + // cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl; reloop = true; } else { reloop = false; @@ -1102,9 +1102,7 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen no_capture_stuff_to_do: - if (_playlist) { - midi_playlist()->clear_note_trackers (); - } + reset_tracker (); } void @@ -1134,6 +1132,10 @@ MidiDiskstream::transport_looped (framepos_t transport_frame) last_recordable_frame = max_framepos; was_recording = true; } + + if (!Config->get_seamless_loop()) { + reset_tracker (); + } } void @@ -1477,3 +1479,15 @@ MidiDiskstream::get_gui_feed_buffer () const b->copy (_gui_feed_buffer); return b; } + +void +MidiDiskstream::reset_tracker () +{ + _playback_buf->reset_tracker (); + + boost::shared_ptr mp (midi_playlist()); + + if (mp) { + mp->clear_note_trackers (); + } +} diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc index edadc225b0..39f603a6e9 100644 --- a/libs/ardour/midi_playlist.cc +++ b/libs/ardour/midi_playlist.cc @@ -83,8 +83,16 @@ MidiPlaylist::~MidiPlaylist () } template -struct EventsSortByTime { +struct EventsSortByTimeAndType { bool operator() (Evoral::Event