Ardour  9.2-654-gd2ed0bd940
Sequence.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008-2016 David Robillard <d@drobilla.net>
3  * Copyright (C) 2009-2012 Hans Baier <hansfbaier@googlemail.com>
4  * Copyright (C) 2009-2013 Paul Davis <paul@linuxaudiosystems.com>
5  * Copyright (C) 2010-2011 Carl Hetherington <carl@carlh.net>
6  * Copyright (C) 2013-2015 John Emmas <john@creativepost.co.uk>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #ifndef EVORAL_SEQUENCE_HPP
24 #define EVORAL_SEQUENCE_HPP
25 
26 #include <list>
27 #include <memory>
28 #include <queue>
29 #include <set>
30 #include <utility>
31 #include <vector>
32 
33 #include "pbd/mutex.h"
34 #include "pbd/rwlock.h"
35 
36 #include "evoral/visibility.h"
37 #include "evoral/Note.h"
38 #include "evoral/ControlSet.h"
39 #include "evoral/ControlList.h"
40 #include "evoral/PatchChange.h"
41 
42 namespace Evoral {
43 
44 class Parameter;
45 class TypeMap;
46 template<typename Time> class EventSink;
47 template<typename Time> class Note;
48 template<typename Time> class Event;
49 
52 class /*LIBEVORAL_API*/ ControlIterator {
53 public:
54  ControlIterator(std::shared_ptr<const ControlList> al, Temporal::timepos_t const & ax, double ay)
55  : list(al)
56  , x(ax)
57  , y(ay)
58  {}
59 
60  std::shared_ptr<const ControlList> list;
62  double y;
63 };
64 
65 
69 template<typename Time>
70 class LIBEVORAL_API Sequence : virtual public ControlSet {
71 public:
72  Sequence(const TypeMap& type_map);
73  Sequence(const Sequence<Time>& other);
74 
75 protected:
76  struct WriteLockImpl {
78  : sequence_lock(new PBD::RWLock::WriterLock(s))
79  , control_lock(new PBD::Mutex::Lock(c)) { }
81  delete sequence_lock;
82  delete control_lock;
83  }
86  };
87 
88 public:
89 
90  typedef typename std::shared_ptr<Evoral::Note<Time> > NotePtr;
91  typedef typename std::weak_ptr<Evoral::Note<Time> > WeakNotePtr;
92  typedef typename std::shared_ptr<const Evoral::Note<Time> > constNotePtr;
93  typedef typename std::set<WeakNotePtr, std::owner_less<WeakNotePtr> > WeakActiveNotes;
94 
95  typedef std::shared_ptr<PBD::RWLock::ReaderLock> ReadLock;
96  typedef std::shared_ptr<WriteLockImpl> WriteLock;
97 
98  virtual ReadLock read_lock() const { return ReadLock(new PBD::RWLock::ReaderLock(_lock)); }
99  virtual WriteLock write_lock() { return WriteLock(new WriteLockImpl(_lock, _control_lock)); }
100 
101  void clear();
102 
103  void start_write();
104  bool writing() const { return _writing; }
105 
109  ResolveStuckNotes
110  };
111 
112  void end_write (StuckNoteOption, Time when = Time());
113 
114  void append(const Event<Time>& ev, Evoral::event_id_t evid);
115 
116  const TypeMap& type_map() const { return _type_map; }
117 
118  inline size_t n_notes() const { return _notes.size(); }
119  inline bool empty() const { return _notes.empty() && _sysexes.empty() && _patch_changes.empty() && ControlSet::controls_empty(); }
120 
121  inline static bool note_time_comparator(const std::shared_ptr< const Note<Time> >& a,
122  const std::shared_ptr< const Note<Time> >& b) {
123  return a->time() < b->time();
124  }
125 
126  /* sorts lowest-to-highest */
128  inline bool operator()(const std::shared_ptr< const Note<Time> > a,
129  const std::shared_ptr< const Note<Time> > b) const {
130  return a->note() < b->note();
131  }
132  };
133 
134  /* sorts highest-to-lowest */
136  inline bool operator()(const std::shared_ptr< const Note<Time> > a,
137  const std::shared_ptr< const Note<Time> > b) const {
138  return b->note() < a->note();
139  }
140  };
141 
143  inline bool operator()(const std::shared_ptr< const Note<Time> > a,
144  const std::shared_ptr< const Note<Time> > b) const {
145  return a->time() < b->time();
146  }
147  };
148 
149 #if 0 // NOT USED
150  struct LaterNoteComparator {
151  typedef const Note<Time>* value_type;
152  inline bool operator()(const std::shared_ptr< const Note<Time> > a,
153  const std::shared_ptr< const Note<Time> > b) const {
154  return a->time() > b->time();
155  }
156  };
157 #endif
158 
160  typedef const Note<Time>* value_type;
161  inline bool operator()(const std::shared_ptr< const Note<Time> > a,
162  const std::shared_ptr< const Note<Time> > b) const {
163  return a->end_time() > b->end_time();
164  }
165  };
166 
167  typedef std::multiset<NotePtr, EarlierNoteComparator> Notes;
168  inline Notes& notes() { return _notes; }
169  inline const Notes& notes() const { return _notes; }
170 
182  };
183 
184  void get_notes (Notes&, NoteOperator, uint8_t val, int chan_mask = 0) const;
185 
189 
192  FirstOnFirstOff
193  };
194 
195  bool overlapping_pitches_accepted() const { return _overlapping_pitches_accepted; }
196  void overlapping_pitches_accepted(bool yn) { _overlapping_pitches_accepted = yn; }
197  OverlapPitchResolution overlap_pitch_resolution() const { return _overlap_pitch_resolution; }
199 
200  void set_notes (const typename Sequence<Time>::Notes& n);
201 
202  typedef std::shared_ptr< Event<Time> > SysExPtr;
203  typedef std::shared_ptr<const Event<Time> > constSysExPtr;
204 
206  inline bool operator() (constSysExPtr a, constSysExPtr b) const {
207  return a->time() < b->time();
208  }
209  };
210 
211  typedef std::multiset<SysExPtr, EarlierSysExComparator> SysExes;
212  inline SysExes& sysexes() { return _sysexes; }
213  inline const SysExes& sysexes() const { return _sysexes; }
214 
215  typedef std::shared_ptr<PatchChange<Time> > PatchChangePtr;
216  typedef std::shared_ptr<const PatchChange<Time> > constPatchChangePtr;
217 
219  inline bool operator() (constPatchChangePtr a, constPatchChangePtr b) const {
220  return a->time() < b->time();
221  }
222  };
223 
224  typedef std::multiset<PatchChangePtr, EarlierPatchChangeComparator> PatchChanges;
225  inline PatchChanges& patch_changes () { return _patch_changes; }
226  inline const PatchChanges& patch_changes () const { return _patch_changes; }
227 
228 private:
229  typedef std::priority_queue<NotePtr, std::deque<NotePtr>, LaterNoteEndComparator> ActiveNotes;
230 public:
231 
234  public:
237  Time t,
238  bool force_discrete,
239  std::set<Evoral::Parameter> const & filtered,
240  WeakActiveNotes const* active_notes = 0);
241 
242  inline bool valid() const { return !_is_end && _event; }
243 
244  void invalidate (bool preserve_notes);
245 
246  const Event<Time>& operator*() const { return *_event; }
247  const std::shared_ptr< const Event<Time> > operator->() const { return _event; }
248 
249  const const_iterator& operator++(); // prefix only
250 
251  bool operator==(const const_iterator& other) const;
252  bool operator!=(const const_iterator& other) const { return ! operator==(other); }
253 
255 
257 
258  private:
259  friend class Sequence<Time>;
260 
261  Time choose_next(Time earliest_t);
262  void set_event();
263 
264  typedef std::vector<ControlIterator> ControlIterators;
265  enum MIDIMessageType { NIL, NOTE_ON, NOTE_OFF, CONTROL, SYSEX, PATCH_CHANGE };
266 
268  std::shared_ptr< Event<Time> > _event;
275  bool _is_end;
277  typename Notes::const_iterator _note_iter;
278  typename SysExes::const_iterator _sysex_iter;
279  typename PatchChanges::const_iterator _patch_change_iter;
281  ControlIterators::iterator _control_iter;
283  };
284 
286  Time t = Time(),
287  bool force_discrete = false,
288  const std::set<Evoral::Parameter>& f = std::set<Evoral::Parameter>(),
289  WeakActiveNotes const * active_notes = 0) const {
290  return const_iterator (*this, t, force_discrete, f, active_notes);
291  }
292 
293  const const_iterator& end() const { return _end_iter; }
294 
295  void dump (std::ostream&, const_iterator x, uint32_t limit = 0) const;
296 
297  // CONST iterator implementations (x3)
298  typename Notes::const_iterator note_lower_bound (Time t) const;
299  typename PatchChanges::const_iterator patch_change_lower_bound (Time t) const;
300  typename SysExes::const_iterator sysex_lower_bound (Time t) const;
301 
302  // NON-CONST iterator implementations (x3)
303  typename Notes::iterator note_lower_bound (Time t);
304  typename PatchChanges::iterator patch_change_lower_bound (Time t);
305  typename SysExes::iterator sysex_lower_bound (Time t);
306 
307  bool control_to_midi_event(std::shared_ptr< Event<Time> >& ev,
308  const ControlIterator& iter) const;
309 
310  bool edited() const { return _edited; }
311  void set_edited(bool yn) { _edited = yn; }
312 
313  bool contains (const NotePtr& ev) const;
314 
315  bool add_note_unlocked (const NotePtr note, void* arg = 0);
317 
320 
323 
324  uint8_t lowest_note() const { return _lowest_note; }
325  uint8_t highest_note() const { return _highest_note; }
326 
327  uint16_t channels_present () const { return _channels_present; }
328 
329  Time duration() const { return _duration; }
330  void set_duration (Time const &);
331 
332  void shift (Time const &);
333 
334 protected:
335  bool _edited;
339  bool _writing;
340 
341  virtual int resolve_overlaps_unlocked (const NotePtr, void* /* arg */ = 0) {
342  return 0;
343  }
344 
345  typedef std::multiset<NotePtr, NoteNumberComparator> Pitches;
346  inline Pitches& pitches(uint8_t chan) { return _pitches[chan&0xf]; }
347  inline const Pitches& pitches(uint8_t chan) const { return _pitches[chan&0xf]; }
348 
349  virtual void control_list_marked_dirty ();
350 
351 private:
352  friend class const_iterator;
353 
354  bool contains_unlocked (const NotePtr& ev) const;
355 
358  void append_control_unlocked(const Parameter& param, Time time, double value, Evoral::event_id_t);
361 
362  void get_notes_by_pitch (Notes&, NoteOperator, uint8_t val, int chan_mask = 0) const;
363  void get_notes_by_velocity (Notes&, NoteOperator, uint8_t val, int chan_mask = 0) const;
364 
366 
367  Notes _notes; // notes indexed by time
368  Pitches _pitches[16]; // notes indexed by channel+pitch
371 
372  typedef std::multiset<NotePtr, EarlierNoteComparator> WriteNotes;
373  WriteNotes _write_notes[16];
374 
379  int _bank[16];
380 
383 
384  uint8_t _lowest_note;
385  uint8_t _highest_note;
387 
388  Time _duration;
390 
391  void update_duration_unlocked (Time const &, bool can_shorten = false);
392 };
393 
394 
395 } // namespace Evoral
396 
397 template<typename Time> /*LIBEVORAL_API*/ std::ostream& operator<<(std::ostream& o, const Evoral::Sequence<Time>& s) { s.dump (o); return o; }
398 
399 
400 #endif // EVORAL_SEQUENCE_HPP
std::ostream & operator<<(std::ostream &o, const Evoral::Sequence< Time > &s)
Definition: Sequence.h:397
std::shared_ptr< const ControlList > list
Definition: Sequence.h:60
Temporal::timepos_t x
Definition: Sequence.h:61
ControlIterator(std::shared_ptr< const ControlList > al, Temporal::timepos_t const &ax, double ay)
Definition: Sequence.h:54
virtual bool controls_empty() const
Definition: ControlSet.h:70
Time time() const
Definition: Note.h:61
const Event< Time > & operator*() const
Definition: Sequence.h:246
void get_active_notes(WeakActiveNotes &) const
const_iterator & operator=(const const_iterator &other)
ControlIterators _control_iters
Definition: Sequence.h:280
Time choose_next(Time earliest_t)
const Sequence< Time > * _seq
Definition: Sequence.h:267
PatchChanges::const_iterator _patch_change_iter
Definition: Sequence.h:279
SysExes::const_iterator _sysex_iter
Definition: Sequence.h:278
bool operator==(const const_iterator &other) const
Sequence::ReadLock _lock
Definition: Sequence.h:276
std::vector< ControlIterator > ControlIterators
Definition: Sequence.h:264
const std::shared_ptr< const Event< Time > > operator->() const
Definition: Sequence.h:247
const const_iterator & operator++()
Notes::const_iterator _note_iter
Definition: Sequence.h:277
bool operator!=(const const_iterator &other) const
Definition: Sequence.h:252
ControlIterators::iterator _control_iter
Definition: Sequence.h:281
const_iterator(const Sequence< Time > &seq, Time t, bool force_discrete, std::set< Evoral::Parameter > const &filtered, WeakActiveNotes const *active_notes=0)
void invalidate(bool preserve_notes)
std::shared_ptr< Event< Time > > _event
Definition: Sequence.h:268
PatchChanges::const_iterator patch_change_lower_bound(Time t) const
void set_edited(bool yn)
Definition: Sequence.h:311
std::shared_ptr< const Event< Time > > constSysExPtr
Definition: Sequence.h:203
bool overlapping_pitches_accepted() const
Definition: Sequence.h:195
bool empty() const
Definition: Sequence.h:119
void shift(Time const &)
const_iterator begin(Time t=Time(), bool force_discrete=false, const std::set< Evoral::Parameter > &f=std::set< Evoral::Parameter >(), WeakActiveNotes const *active_notes=0) const
Definition: Sequence.h:285
std::shared_ptr< PBD::RWLock::ReaderLock > ReadLock
Definition: Sequence.h:95
OverlapPitchResolution _overlap_pitch_resolution
Definition: Sequence.h:337
bool add_note_unlocked(const NotePtr note, void *arg=0)
std::multiset< NotePtr, EarlierNoteComparator > WriteNotes
Definition: Sequence.h:372
Notes::const_iterator note_lower_bound(Time t) const
void set_notes(const typename Sequence< Time >::Notes &n)
std::shared_ptr< const Evoral::Note< Time > > constNotePtr
Definition: Sequence.h:92
SysExes::iterator sysex_lower_bound(Time t)
static bool note_time_comparator(const std::shared_ptr< const Note< Time > > &a, const std::shared_ptr< const Note< Time > > &b)
Definition: Sequence.h:121
const Pitches & pitches(uint8_t chan) const
Definition: Sequence.h:347
size_t n_notes() const
Definition: Sequence.h:118
void set_duration(Time const &)
void append_note_on_unlocked(const Event< Time > &event, Evoral::event_id_t)
std::shared_ptr< PatchChange< Time > > PatchChangePtr
Definition: Sequence.h:215
bool _overlapping_pitches_accepted
Definition: Sequence.h:336
const PatchChanges & patch_changes() const
Definition: Sequence.h:226
void get_notes(Notes &, NoteOperator, uint8_t val, int chan_mask=0) const
bool writing() const
Definition: Sequence.h:104
const const_iterator _end_iter
Definition: Sequence.h:381
OverlapPitchResolution overlap_pitch_resolution() const
Definition: Sequence.h:197
std::priority_queue< NotePtr, std::deque< NotePtr >, LaterNoteEndComparator > ActiveNotes
Definition: Sequence.h:229
std::shared_ptr< const PatchChange< Time > > constPatchChangePtr
Definition: Sequence.h:216
uint8_t highest_note() const
Definition: Sequence.h:325
Notes::iterator note_lower_bound(Time t)
const SysExes & sysexes() const
Definition: Sequence.h:213
virtual ReadLock read_lock() const
Definition: Sequence.h:98
PatchChanges & patch_changes()
Definition: Sequence.h:225
const const_iterator & end() const
Definition: Sequence.h:293
void dump(std::ostream &, const_iterator x, uint32_t limit=0) const
void append_sysex_unlocked(const Event< Time > &ev, Evoral::event_id_t)
void remove_note_unlocked(const constNotePtr note)
PatchChanges _patch_changes
Definition: Sequence.h:370
void end_write(StuckNoteOption, Time when=Time())
void remove_overlapping_notes()
std::multiset< SysExPtr, EarlierSysExComparator > SysExes
Definition: Sequence.h:211
PatchChanges::iterator patch_change_lower_bound(Time t)
@ VelocityGreaterThanOrEqual
Definition: Sequence.h:181
@ VelocityLessThanOrEqual
Definition: Sequence.h:179
@ PitchGreaterThanOrEqual
Definition: Sequence.h:176
void overlapping_pitches_accepted(bool yn)
Definition: Sequence.h:196
void add_sysex_unlocked(const SysExPtr)
void trim_overlapping_notes()
bool contains(const NotePtr &ev) const
SysExes & sysexes()
Definition: Sequence.h:212
std::multiset< NotePtr, NoteNumberComparator > Pitches
Definition: Sequence.h:345
virtual WriteLock write_lock()
Definition: Sequence.h:99
uint8_t lowest_note() const
Definition: Sequence.h:324
bool control_to_midi_event(std::shared_ptr< Event< Time > > &ev, const ControlIterator &iter) const
uint16_t channels_present() const
Definition: Sequence.h:327
const Notes & notes() const
Definition: Sequence.h:169
Sequence(const Sequence< Time > &other)
bool _explicit_duration
Definition: Sequence.h:389
SysExes _sysexes
Definition: Sequence.h:369
std::multiset< NotePtr, EarlierNoteComparator > Notes
Definition: Sequence.h:167
void get_notes_by_velocity(Notes &, NoteOperator, uint8_t val, int chan_mask=0) const
void update_duration_unlocked(Time const &, bool can_shorten=false)
std::set< WeakNotePtr, std::owner_less< WeakNotePtr > > WeakActiveNotes
Definition: Sequence.h:93
void remove_duplicate_notes()
void append(const Event< Time > &ev, Evoral::event_id_t evid)
bool contains_unlocked(const NotePtr &ev) const
SysExes::const_iterator sysex_lower_bound(Time t) const
void remove_sysex_unlocked(const SysExPtr)
const TypeMap & type_map() const
Definition: Sequence.h:116
void append_patch_change_unlocked(const PatchChange< Time > &, Evoral::event_id_t)
uint8_t _lowest_note
Definition: Sequence.h:384
Time duration() const
Definition: Sequence.h:329
const TypeMap & _type_map
Definition: Sequence.h:365
Sequence(const TypeMap &type_map)
void append_control_unlocked(const Parameter &param, Time time, double value, Evoral::event_id_t)
void append_note_off_unlocked(const Event< Time > &event)
std::shared_ptr< Event< Time > > SysExPtr
Definition: Sequence.h:202
std::shared_ptr< Evoral::Note< Time > > NotePtr
Definition: Sequence.h:90
Notes & notes()
Definition: Sequence.h:168
std::weak_ptr< Evoral::Note< Time > > WeakNotePtr
Definition: Sequence.h:91
void get_notes_by_pitch(Notes &, NoteOperator, uint8_t val, int chan_mask=0) const
void remove_patch_change_unlocked(const constPatchChangePtr)
uint8_t _highest_note
Definition: Sequence.h:385
bool edited() const
Definition: Sequence.h:310
void set_overlap_pitch_resolution(OverlapPitchResolution opr)
Pitches & pitches(uint8_t chan)
Definition: Sequence.h:346
virtual void control_list_marked_dirty()
void add_patch_change_unlocked(const PatchChangePtr)
PBD::RWLock _lock
Definition: Sequence.h:338
std::multiset< PatchChangePtr, EarlierPatchChangeComparator > PatchChanges
Definition: Sequence.h:224
uint16_t _channels_present
Definition: Sequence.h:386
std::shared_ptr< WriteLockImpl > WriteLock
Definition: Sequence.h:96
virtual int resolve_overlaps_unlocked(const NotePtr, void *=0)
Definition: Sequence.h:341
#define LIBEVORAL_API
Definition: editor.h:85
int32_t event_id_t
Definition: axis_view.h:42
bool operator==(const ProcessorSelection &a, const ProcessorSelection &b)
bool operator()(const std::shared_ptr< const Note< Time > > a, const std::shared_ptr< const Note< Time > > b) const
Definition: Sequence.h:143
bool operator()(const std::shared_ptr< const Note< Time > > a, const std::shared_ptr< const Note< Time > > b) const
Definition: Sequence.h:161
bool operator()(const std::shared_ptr< const Note< Time > > a, const std::shared_ptr< const Note< Time > > b) const
Definition: Sequence.h:128
bool operator()(const std::shared_ptr< const Note< Time > > a, const std::shared_ptr< const Note< Time > > b) const
Definition: Sequence.h:136
PBD::RWLock::WriterLock * sequence_lock
Definition: Sequence.h:84
WriteLockImpl(PBD::RWLock &s, PBD::Mutex &c)
Definition: Sequence.h:77
PBD::Mutex::Lock * control_lock
Definition: Sequence.h:85