X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Fmidi_playlist.h;h=a84c4648018ddfbd879c65d1db214741d39024f0;hb=eaca325ce81c63888ee70305ad384102e46757be;hp=b118214c9e2a2a2aaf5f6a23b3ffc86ec7231c16;hpb=c0e6f8e4c324c3f44613949b59acd9e864ab263d;p=ardour.git diff --git a/libs/ardour/ardour/midi_playlist.h b/libs/ardour/ardour/midi_playlist.h index b118214c9e..a84c464801 100644 --- a/libs/ardour/ardour/midi_playlist.h +++ b/libs/ardour/ardour/midi_playlist.h @@ -23,17 +23,30 @@ #include #include +#include + #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 class EventSink; +class Beats; +} + namespace ARDOUR { -class Session; +class BeatsFramesConverter; +class MidiChannelFilter; class MidiRegion; +class Session; class Source; + template class MidiRingBuffer; class LIBARDOUR_API MidiPlaylist : public ARDOUR::Playlist @@ -42,13 +55,31 @@ public: MidiPlaylist (Session&, const XMLNode&, bool hidden = false); MidiPlaylist (Session&, std::string name, bool hidden = false); MidiPlaylist (boost::shared_ptr other, std::string name, bool hidden = false); - MidiPlaylist (boost::shared_ptr other, framepos_t start, framecnt_t cnt, - std::string name, bool hidden = false); + + /** This constructor does NOT notify others (session) */ + MidiPlaylist (boost::shared_ptr 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& 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 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, + 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& dst, framepos_t time); protected: - void remove_dependents (boost::shared_ptr region); private: - void dump () const; + typedef Evoral::Note Note; + typedef Evoral::Event Event; - bool region_changed (const PBD::PropertyChange&, boost::shared_ptr); + struct RegionTracker : public boost::noncopyable { + MidiStateTracker tracker; ///< Active note tracker + NoteFixer fixer; ///< Edit compensation + }; - NoteMode _note_mode; + typedef std::map< Region*, boost::shared_ptr > NoteTrackers; - typedef std::map NoteTrackers; - NoteTrackers _note_trackers; + void dump () const; + NoteTrackers _note_trackers; + NoteMode _note_mode; + framepos_t _read_end; }; } /* namespace ARDOUR */