Ardour  9.2-79-gba93f2fe52
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 
127  inline bool operator()(const std::shared_ptr< const Note<Time> > a,
128  const std::shared_ptr< const Note<Time> > b) const {
129  return a->note() < b->note();
130  }
131  };
132 
134  inline bool operator()(const std::shared_ptr< const Note<Time> > a,
135  const std::shared_ptr< const Note<Time> > b) const {
136  return a->time() < b->time();
137  }
138  };
139 
140 #if 0 // NOT USED
141  struct LaterNoteComparator {
142  typedef const Note<Time>* value_type;
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 #endif
149 
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->end_time() > b->end_time();
155  }
156  };
157 
158  typedef std::multiset<NotePtr, EarlierNoteComparator> Notes;
159  inline Notes& notes() { return _notes; }
160  inline const Notes& notes() const { return _notes; }
161 
173  };
174 
175  void get_notes (Notes&, NoteOperator, uint8_t val, int chan_mask = 0) const;
176 
180 
183  FirstOnFirstOff
184  };
185 
186  bool overlapping_pitches_accepted() const { return _overlapping_pitches_accepted; }
187  void overlapping_pitches_accepted(bool yn) { _overlapping_pitches_accepted = yn; }
188  OverlapPitchResolution overlap_pitch_resolution() const { return _overlap_pitch_resolution; }
190 
191  void set_notes (const typename Sequence<Time>::Notes& n);
192 
193  typedef std::shared_ptr< Event<Time> > SysExPtr;
194  typedef std::shared_ptr<const Event<Time> > constSysExPtr;
195 
197  inline bool operator() (constSysExPtr a, constSysExPtr b) const {
198  return a->time() < b->time();
199  }
200  };
201 
202  typedef std::multiset<SysExPtr, EarlierSysExComparator> SysExes;
203  inline SysExes& sysexes() { return _sysexes; }
204  inline const SysExes& sysexes() const { return _sysexes; }
205 
206  typedef std::shared_ptr<PatchChange<Time> > PatchChangePtr;
207  typedef std::shared_ptr<const PatchChange<Time> > constPatchChangePtr;
208 
210  inline bool operator() (constPatchChangePtr a, constPatchChangePtr b) const {
211  return a->time() < b->time();
212  }
213  };
214 
215  typedef std::multiset<PatchChangePtr, EarlierPatchChangeComparator> PatchChanges;
216  inline PatchChanges& patch_changes () { return _patch_changes; }
217  inline const PatchChanges& patch_changes () const { return _patch_changes; }
218 
219 private:
220  typedef std::priority_queue<NotePtr, std::deque<NotePtr>, LaterNoteEndComparator> ActiveNotes;
221 public:
222 
225  public:
228  Time t,
229  bool force_discrete,
230  std::set<Evoral::Parameter> const & filtered,
231  WeakActiveNotes const* active_notes = 0);
232 
233  inline bool valid() const { return !_is_end && _event; }
234 
235  void invalidate (bool preserve_notes);
236 
237  const Event<Time>& operator*() const { return *_event; }
238  const std::shared_ptr< const Event<Time> > operator->() const { return _event; }
239 
240  const const_iterator& operator++(); // prefix only
241 
242  bool operator==(const const_iterator& other) const;
243  bool operator!=(const const_iterator& other) const { return ! operator==(other); }
244 
246 
248 
249  private:
250  friend class Sequence<Time>;
251 
252  Time choose_next(Time earliest_t);
253  void set_event();
254 
255  typedef std::vector<ControlIterator> ControlIterators;
256  enum MIDIMessageType { NIL, NOTE_ON, NOTE_OFF, CONTROL, SYSEX, PATCH_CHANGE };
257 
259  std::shared_ptr< Event<Time> > _event;
266  bool _is_end;
268  typename Notes::const_iterator _note_iter;
269  typename SysExes::const_iterator _sysex_iter;
270  typename PatchChanges::const_iterator _patch_change_iter;
272  ControlIterators::iterator _control_iter;
274  };
275 
277  Time t = Time(),
278  bool force_discrete = false,
279  const std::set<Evoral::Parameter>& f = std::set<Evoral::Parameter>(),
280  WeakActiveNotes const * active_notes = 0) const {
281  return const_iterator (*this, t, force_discrete, f, active_notes);
282  }
283 
284  const const_iterator& end() const { return _end_iter; }
285 
286  void dump (std::ostream&, const_iterator x, uint32_t limit = 0) const;
287 
288  // CONST iterator implementations (x3)
289  typename Notes::const_iterator note_lower_bound (Time t) const;
290  typename PatchChanges::const_iterator patch_change_lower_bound (Time t) const;
291  typename SysExes::const_iterator sysex_lower_bound (Time t) const;
292 
293  // NON-CONST iterator implementations (x3)
294  typename Notes::iterator note_lower_bound (Time t);
295  typename PatchChanges::iterator patch_change_lower_bound (Time t);
296  typename SysExes::iterator sysex_lower_bound (Time t);
297 
298  bool control_to_midi_event(std::shared_ptr< Event<Time> >& ev,
299  const ControlIterator& iter) const;
300 
301  bool edited() const { return _edited; }
302  void set_edited(bool yn) { _edited = yn; }
303 
304  bool contains (const NotePtr& ev) const;
305 
306  bool add_note_unlocked (const NotePtr note, void* arg = 0);
308 
311 
314 
315  uint8_t lowest_note() const { return _lowest_note; }
316  uint8_t highest_note() const { return _highest_note; }
317 
318  uint16_t channels_present () const { return _channels_present; }
319 
320  Time duration() const { return _duration; }
321  void set_duration (Time const &);
322 
323  void shift (Time const &);
324 
325 protected:
326  bool _edited;
330  bool _writing;
331 
332  virtual int resolve_overlaps_unlocked (const NotePtr, void* /* arg */ = 0) {
333  return 0;
334  }
335 
336  typedef std::multiset<NotePtr, NoteNumberComparator> Pitches;
337  inline Pitches& pitches(uint8_t chan) { return _pitches[chan&0xf]; }
338  inline const Pitches& pitches(uint8_t chan) const { return _pitches[chan&0xf]; }
339 
340  virtual void control_list_marked_dirty ();
341 
342 private:
343  friend class const_iterator;
344 
345  bool contains_unlocked (const NotePtr& ev) const;
346 
349  void append_control_unlocked(const Parameter& param, Time time, double value, Evoral::event_id_t);
352 
353  void get_notes_by_pitch (Notes&, NoteOperator, uint8_t val, int chan_mask = 0) const;
354  void get_notes_by_velocity (Notes&, NoteOperator, uint8_t val, int chan_mask = 0) const;
355 
357 
358  Notes _notes; // notes indexed by time
359  Pitches _pitches[16]; // notes indexed by channel+pitch
362 
363  typedef std::multiset<NotePtr, EarlierNoteComparator> WriteNotes;
364  WriteNotes _write_notes[16];
365 
370  int _bank[16];
371 
374 
375  uint8_t _lowest_note;
376  uint8_t _highest_note;
378 
379  Time _duration;
381 
382  void update_duration_unlocked (Time const &, bool can_shorten = false);
383 };
384 
385 
386 } // namespace Evoral
387 
388 template<typename Time> /*LIBEVORAL_API*/ std::ostream& operator<<(std::ostream& o, const Evoral::Sequence<Time>& s) { s.dump (o); return o; }
389 
390 
391 #endif // EVORAL_SEQUENCE_HPP
std::ostream & operator<<(std::ostream &o, const Evoral::Sequence< Time > &s)
Definition: Sequence.h:388
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:237
void get_active_notes(WeakActiveNotes &) const
const_iterator & operator=(const const_iterator &other)
ControlIterators _control_iters
Definition: Sequence.h:271
Time choose_next(Time earliest_t)
const Sequence< Time > * _seq
Definition: Sequence.h:258
PatchChanges::const_iterator _patch_change_iter
Definition: Sequence.h:270
SysExes::const_iterator _sysex_iter
Definition: Sequence.h:269
bool operator==(const const_iterator &other) const
Sequence::ReadLock _lock
Definition: Sequence.h:267
std::vector< ControlIterator > ControlIterators
Definition: Sequence.h:255
const std::shared_ptr< const Event< Time > > operator->() const
Definition: Sequence.h:238
const const_iterator & operator++()
Notes::const_iterator _note_iter
Definition: Sequence.h:268
bool operator!=(const const_iterator &other) const
Definition: Sequence.h:243
ControlIterators::iterator _control_iter
Definition: Sequence.h:272
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:259
PatchChanges::const_iterator patch_change_lower_bound(Time t) const
void set_edited(bool yn)
Definition: Sequence.h:302
std::shared_ptr< const Event< Time > > constSysExPtr
Definition: Sequence.h:194
bool overlapping_pitches_accepted() const
Definition: Sequence.h:186
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:276
std::shared_ptr< PBD::RWLock::ReaderLock > ReadLock
Definition: Sequence.h:95
OverlapPitchResolution _overlap_pitch_resolution
Definition: Sequence.h:328
bool add_note_unlocked(const NotePtr note, void *arg=0)
std::multiset< NotePtr, EarlierNoteComparator > WriteNotes
Definition: Sequence.h:363
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:338
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:206
bool _overlapping_pitches_accepted
Definition: Sequence.h:327
const PatchChanges & patch_changes() const
Definition: Sequence.h:217
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:372
OverlapPitchResolution overlap_pitch_resolution() const
Definition: Sequence.h:188
std::priority_queue< NotePtr, std::deque< NotePtr >, LaterNoteEndComparator > ActiveNotes
Definition: Sequence.h:220
std::shared_ptr< const PatchChange< Time > > constPatchChangePtr
Definition: Sequence.h:207
uint8_t highest_note() const
Definition: Sequence.h:316
Notes::iterator note_lower_bound(Time t)
const SysExes & sysexes() const
Definition: Sequence.h:204
virtual ReadLock read_lock() const
Definition: Sequence.h:98
PatchChanges & patch_changes()
Definition: Sequence.h:216
const const_iterator & end() const
Definition: Sequence.h:284
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:361
void end_write(StuckNoteOption, Time when=Time())
void remove_overlapping_notes()
std::multiset< SysExPtr, EarlierSysExComparator > SysExes
Definition: Sequence.h:202
PatchChanges::iterator patch_change_lower_bound(Time t)
@ VelocityGreaterThanOrEqual
Definition: Sequence.h:172
@ VelocityLessThanOrEqual
Definition: Sequence.h:170
@ PitchGreaterThanOrEqual
Definition: Sequence.h:167
void overlapping_pitches_accepted(bool yn)
Definition: Sequence.h:187
void add_sysex_unlocked(const SysExPtr)
void trim_overlapping_notes()
bool contains(const NotePtr &ev) const
SysExes & sysexes()
Definition: Sequence.h:203
std::multiset< NotePtr, NoteNumberComparator > Pitches
Definition: Sequence.h:336
virtual WriteLock write_lock()
Definition: Sequence.h:99
uint8_t lowest_note() const
Definition: Sequence.h:315
bool control_to_midi_event(std::shared_ptr< Event< Time > > &ev, const ControlIterator &iter) const
uint16_t channels_present() const
Definition: Sequence.h:318
const Notes & notes() const
Definition: Sequence.h:160
Sequence(const Sequence< Time > &other)
bool _explicit_duration
Definition: Sequence.h:380
SysExes _sysexes
Definition: Sequence.h:360
std::multiset< NotePtr, EarlierNoteComparator > Notes
Definition: Sequence.h:158
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:375
Time duration() const
Definition: Sequence.h:320
const TypeMap & _type_map
Definition: Sequence.h:356
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:193
std::shared_ptr< Evoral::Note< Time > > NotePtr
Definition: Sequence.h:90
Notes & notes()
Definition: Sequence.h:159
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:376
bool edited() const
Definition: Sequence.h:301
void set_overlap_pitch_resolution(OverlapPitchResolution opr)
Pitches & pitches(uint8_t chan)
Definition: Sequence.h:337
virtual void control_list_marked_dirty()
void add_patch_change_unlocked(const PatchChangePtr)
PBD::RWLock _lock
Definition: Sequence.h:329
std::multiset< PatchChangePtr, EarlierPatchChangeComparator > PatchChanges
Definition: Sequence.h:215
uint16_t _channels_present
Definition: Sequence.h:377
std::shared_ptr< WriteLockImpl > WriteLock
Definition: Sequence.h:96
virtual int resolve_overlaps_unlocked(const NotePtr, void *=0)
Definition: Sequence.h:332
#define LIBEVORAL_API
Definition: editor.h:87
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:134
bool operator()(const std::shared_ptr< const Note< Time > > a, const std::shared_ptr< const Note< Time > > b) const
Definition: Sequence.h:152
bool operator()(const std::shared_ptr< const Note< Time > > a, const std::shared_ptr< const Note< Time > > b) const
Definition: Sequence.h:127
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