NO-OP session-property comments
[ardour.git] / libs / ardour / ardour / midi_playlist.h
index 99d0b983216ed0c0597bce3e2f1e2702e0c468d7..a84c4648018ddfbd879c65d1db214741d39024f0 100644 (file)
 #include <vector>
 #include <list>
 
+#include <boost/utility.hpp>
+
 #include "ardour/ardour.h"
-#include "ardour/playlist.h"
+#include "ardour/midi_model.h"
 #include "ardour/midi_state_tracker.h"
+#include "ardour/note_fixer.h"
+#include "ardour/playlist.h"
+#include "evoral/Note.hpp"
 #include "evoral/Parameter.hpp"
 
+namespace Evoral {
+template<typename Time> class EventSink;
+class                         Beats;
+}
+
 namespace ARDOUR
 {
 
-class Session;
+class BeatsFramesConverter;
+class MidiChannelFilter;
 class MidiRegion;
+class Session;
 class Source;
+
 template<typename T> class MidiRingBuffer;
 
-class MidiPlaylist : public ARDOUR::Playlist
+class LIBARDOUR_API MidiPlaylist : public ARDOUR::Playlist
 {
 public:
        MidiPlaylist (Session&, const XMLNode&, bool hidden = false);
        MidiPlaylist (Session&, std::string name, bool hidden = false);
        MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, std::string name, bool hidden = false);
-       MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, framepos_t start, framecnt_t cnt,
-                     std::string name, bool hidden = false);
+
+       /** This constructor does NOT notify others (session) */
+       MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other,
+                     framepos_t                            start,
+                     framecnt_t                            cnt,
+                     std::string                           name,
+                     bool                                  hidden = false);
 
        ~MidiPlaylist ();
 
+       /** Read a range from the playlist into an event sink.
+        *
+        * @param buf Destination for events.
+        * @param start First frame of read range.
+        * @param cnt Number of frames in read range.
+        * @param chan_n Must be 0 (this is the audio-style "channel", where each
+        * channel is backed by a separate region, not MIDI channels, which all
+        * exist in the same region and are not handled here).
+        * @return The number of frames read (time, not an event count).
+        */
        framecnt_t read (Evoral::EventSink<framepos_t>& buf,
-                        framepos_t start, framecnt_t cnt, uint32_t chan_n = 0);
+                        framepos_t                     start,
+                        framecnt_t                     cnt,
+                        uint32_t                       chan_n = 0,
+                        MidiChannelFilter*             filter = NULL);
 
        int set_state (const XMLNode&, int version);
 
@@ -58,22 +89,44 @@ public:
 
        std::set<Evoral::Parameter> contained_automation();
 
-       void clear_note_trackers ();
+       /** Handle a region edit during read.
+        *
+        * This must be called before the command is applied to the model.  Events
+        * are injected into the playlist output to compensate for edits to active
+        * notes and maintain coherent output and tracker state.
+        */
+       void region_edited(boost::shared_ptr<Region>         region,
+                          const MidiModel::NoteDiffCommand* cmd);
+
+       /** Clear all note trackers. */
+       void reset_note_trackers ();
+
+       /** Resolve all pending notes and clear all note trackers.
+        *
+        * @param dst Sink to write note offs to.
+        * @param time Time stamp of all written note offs.
+        */
+       void resolve_note_trackers (Evoral::EventSink<framepos_t>& dst, framepos_t time);
 
 protected:
-
        void remove_dependents (boost::shared_ptr<Region> region);
 
 private:
-       void dump () const;
+       typedef Evoral::Note<Evoral::Beats> Note;
+       typedef Evoral::Event<framepos_t>   Event;
 
-       bool region_changed (const PBD::PropertyChange&, boost::shared_ptr<Region>);
+       struct RegionTracker : public boost::noncopyable {
+               MidiStateTracker tracker;  ///< Active note tracker
+               NoteFixer        fixer;    ///< Edit compensation
+       };
 
-       NoteMode _note_mode;
+       typedef std::map< Region*, boost::shared_ptr<RegionTracker> > NoteTrackers;
 
-       typedef std::map<Region*,MidiStateTracker*> NoteTrackers;
-       NoteTrackers _note_trackers;
+       void dump () const;
 
+       NoteTrackers _note_trackers;
+       NoteMode     _note_mode;
+       framepos_t   _read_end;
 };
 
 } /* namespace ARDOUR */