X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Fmidi_playlist.h;h=a84c4648018ddfbd879c65d1db214741d39024f0;hb=eaca325ce81c63888ee70305ad384102e46757be;hp=dcc202bbf4edc735b7753bd003e34332713e47cc;hpb=449aab3c465bbbf66d221fac3d7ea559f1720357;p=ardour.git diff --git a/libs/ardour/ardour/midi_playlist.h b/libs/ardour/ardour/midi_playlist.h index dcc202bbf4..a84c464801 100644 --- a/libs/ardour/ardour/midi_playlist.h +++ b/libs/ardour/ardour/midi_playlist.h @@ -1,17 +1,17 @@ /* - Copyright (C) 2006 Paul Davis - Written by Dave Robillard, 2006 - + Copyright (C) 2006 Paul Davis + Author: David Robillard + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -23,58 +23,110 @@ #include #include -#include -#include -#include +#include + +#include "ardour/ardour.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 Region; +class BeatsFramesConverter; +class MidiChannelFilter; class MidiRegion; +class Session; class Source; -class MidiRingBuffer; -class MidiPlaylist : public ARDOUR::Playlist +template class MidiRingBuffer; + +class LIBARDOUR_API MidiPlaylist : public ARDOUR::Playlist { public: MidiPlaylist (Session&, const XMLNode&, bool hidden = false); - MidiPlaylist (Session&, string name, bool hidden = false); - MidiPlaylist (boost::shared_ptr other, string name, bool hidden = false); - MidiPlaylist (boost::shared_ptr other, nframes_t start, nframes_t cnt, - string name, bool hidden = false); + MidiPlaylist (Session&, std::string name, bool hidden = false); + MidiPlaylist (boost::shared_ptr other, std::string name, bool hidden = false); - ~MidiPlaylist (); + /** This constructor does NOT notify others (session) */ + MidiPlaylist (boost::shared_ptr other, + framepos_t start, + framecnt_t cnt, + std::string name, + bool hidden = false); - nframes_t read (MidiRingBuffer& buf, - nframes_t start, nframes_t cnt, uint32_t chan_n=0); + ~MidiPlaylist (); - int set_state (const XMLNode&); - UndoAction get_memento() const; + /** 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, + MidiChannelFilter* filter = NULL); + + int set_state (const XMLNode&, int version); bool destroy_region (boost::shared_ptr); - + void set_note_mode (NoteMode m) { _note_mode = m; } - std::set contained_automation(); + std::set contained_automation(); -protected: + /** 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 (); - /* playlist "callbacks" */ + /** 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); - void finalize_split_region (boost::shared_ptr original, boost::shared_ptr left, boost::shared_ptr right); - - void check_dependents (boost::shared_ptr region, bool norefresh); - void refresh_dependents (boost::shared_ptr region); +protected: void remove_dependents (boost::shared_ptr region); private: + typedef Evoral::Note Note; + typedef Evoral::Event Event; + + struct RegionTracker : public boost::noncopyable { + MidiStateTracker tracker; ///< Active note tracker + NoteFixer fixer; ///< Edit compensation + }; + + typedef std::map< Region*, boost::shared_ptr > NoteTrackers; + void dump () const; - bool region_changed (Change, boost::shared_ptr); - - NoteMode _note_mode; + NoteTrackers _note_trackers; + NoteMode _note_mode; + framepos_t _read_end; }; } /* namespace ARDOUR */