Ardour  9.0-pre0-582-g084a23a80d
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 <glibmm/threads.h>
34 
35 #include "evoral/visibility.h"
36 #include "evoral/Note.h"
37 #include "evoral/ControlSet.h"
38 #include "evoral/ControlList.h"
39 #include "evoral/PatchChange.h"
40 
41 namespace Evoral {
42 
43 class Parameter;
44 class TypeMap;
45 template<typename Time> class EventSink;
46 template<typename Time> class Note;
47 template<typename Time> class Event;
48 
51 class /*LIBEVORAL_API*/ ControlIterator {
52 public:
53  ControlIterator(std::shared_ptr<const ControlList> al, Temporal::timepos_t const & ax, double ay)
54  : list(al)
55  , x(ax)
56  , y(ay)
57  {}
58 
59  std::shared_ptr<const ControlList> list;
61  double y;
62 };
63 
64 
68 template<typename Time>
69 class LIBEVORAL_API Sequence : virtual public ControlSet {
70 public:
71  Sequence(const TypeMap& type_map);
72  Sequence(const Sequence<Time>& other);
73 
74 protected:
75  struct WriteLockImpl {
76  WriteLockImpl(Glib::Threads::RWLock& s, Glib::Threads::Mutex& c)
77  : sequence_lock(new Glib::Threads::RWLock::WriterLock(s))
78  , control_lock(new Glib::Threads::Mutex::Lock(c)) { }
80  delete sequence_lock;
81  delete control_lock;
82  }
83  Glib::Threads::RWLock::WriterLock* sequence_lock;
85  };
86 
87 public:
88 
89  typedef typename std::shared_ptr<Evoral::Note<Time> > NotePtr;
90  typedef typename std::weak_ptr<Evoral::Note<Time> > WeakNotePtr;
91  typedef typename std::shared_ptr<const Evoral::Note<Time> > constNotePtr;
92  typedef typename std::set<WeakNotePtr, std::owner_less<WeakNotePtr> > WeakActiveNotes;
93 
94  typedef std::shared_ptr<Glib::Threads::RWLock::ReaderLock> ReadLock;
95  typedef std::shared_ptr<WriteLockImpl> WriteLock;
96 
97  virtual ReadLock read_lock() const { return ReadLock(new Glib::Threads::RWLock::ReaderLock(_lock)); }
98  virtual WriteLock write_lock() { return WriteLock(new WriteLockImpl(_lock, _control_lock)); }
99 
100  void clear();
101 
102  void start_write();
103  bool writing() const { return _writing; }
104 
108  ResolveStuckNotes
109  };
110 
111  void end_write (StuckNoteOption, Time when = Time());
112 
113  void append(const Event<Time>& ev, Evoral::event_id_t evid);
114 
115  const TypeMap& type_map() const { return _type_map; }
116 
117  inline size_t n_notes() const { return _notes.size(); }
118  inline bool empty() const { return _notes.empty() && _sysexes.empty() && _patch_changes.empty() && ControlSet::controls_empty(); }
119 
120  inline static bool note_time_comparator(const std::shared_ptr< const Note<Time> >& a,
121  const std::shared_ptr< const Note<Time> >& b) {
122  return a->time() < b->time();
123  }
124 
126  inline bool operator()(const std::shared_ptr< const Note<Time> > a,
127  const std::shared_ptr< const Note<Time> > b) const {
128  return a->note() < b->note();
129  }
130  };
131 
133  inline bool operator()(const std::shared_ptr< const Note<Time> > a,
134  const std::shared_ptr< const Note<Time> > b) const {
135  return a->time() < b->time();
136  }
137  };
138 
139 #if 0 // NOT USED
140  struct LaterNoteComparator {
141  typedef const Note<Time>* value_type;
142  inline bool operator()(const std::shared_ptr< const Note<Time> > a,
143  const std::shared_ptr< const Note<Time> > b) const {
144  return a->time() > b->time();
145  }
146  };
147 #endif
148 
150  typedef const Note<Time>* value_type;
151  inline bool operator()(const std::shared_ptr< const Note<Time> > a,
152  const std::shared_ptr< const Note<Time> > b) const {
153  return a->end_time() > b->end_time();
154  }
155  };
156 
157  typedef std::multiset<NotePtr, EarlierNoteComparator> Notes;
158  inline Notes& notes() { return _notes; }
159  inline const Notes& notes() const { return _notes; }
160 
172  };
173 
174  void get_notes (Notes&, NoteOperator, uint8_t val, int chan_mask = 0) const;
175 
179 
182  FirstOnFirstOff
183  };
184 
185  bool overlapping_pitches_accepted() const { return _overlapping_pitches_accepted; }
186  void overlapping_pitches_accepted(bool yn) { _overlapping_pitches_accepted = yn; }
187  OverlapPitchResolution overlap_pitch_resolution() const { return _overlap_pitch_resolution; }
189 
190  void set_notes (const typename Sequence<Time>::Notes& n);
191 
192  typedef std::shared_ptr< Event<Time> > SysExPtr;
193  typedef std::shared_ptr<const Event<Time> > constSysExPtr;
194 
196  inline bool operator() (constSysExPtr a, constSysExPtr b) const {
197  return a->time() < b->time();
198  }
199  };
200 
201  typedef std::multiset<SysExPtr, EarlierSysExComparator> SysExes;
202  inline SysExes& sysexes() { return _sysexes; }
203  inline const SysExes& sysexes() const { return _sysexes; }
204 
205  typedef std::shared_ptr<PatchChange<Time> > PatchChangePtr;
206  typedef std::shared_ptr<const PatchChange<Time> > constPatchChangePtr;
207 
209  inline bool operator() (constPatchChangePtr a, constPatchChangePtr b) const {
210  return a->time() < b->time();
211  }
212  };
213 
214  typedef std::multiset<PatchChangePtr, EarlierPatchChangeComparator> PatchChanges;
215  inline PatchChanges& patch_changes () { return _patch_changes; }
216  inline const PatchChanges& patch_changes () const { return _patch_changes; }
217 
218 private:
219  typedef std::priority_queue<NotePtr, std::deque<NotePtr>, LaterNoteEndComparator> ActiveNotes;
220 public:
221 
224  public:
227  Time t,
228  bool force_discrete,
229  std::set<Evoral::Parameter> const & filtered,
230  WeakActiveNotes const* active_notes = 0);
231 
232  inline bool valid() const { return !_is_end && _event; }
233 
234  void invalidate (bool preserve_notes);
235 
236  const Event<Time>& operator*() const { return *_event; }
237  const std::shared_ptr< const Event<Time> > operator->() const { return _event; }
238 
239  const const_iterator& operator++(); // prefix only
240 
241  bool operator==(const const_iterator& other) const;
242  bool operator!=(const const_iterator& other) const { return ! operator==(other); }
243 
245 
247 
248  private:
249  friend class Sequence<Time>;
250 
251  Time choose_next(Time earliest_t);
252  void set_event();
253 
254  typedef std::vector<ControlIterator> ControlIterators;
255  enum MIDIMessageType { NIL, NOTE_ON, NOTE_OFF, CONTROL, SYSEX, PATCH_CHANGE };
256 
258  std::shared_ptr< Event<Time> > _event;
265  bool _is_end;
267  typename Notes::const_iterator _note_iter;
268  typename SysExes::const_iterator _sysex_iter;
269  typename PatchChanges::const_iterator _patch_change_iter;
271  ControlIterators::iterator _control_iter;
273  };
274 
276  Time t = Time(),
277  bool force_discrete = false,
278  const std::set<Evoral::Parameter>& f = std::set<Evoral::Parameter>(),
279  WeakActiveNotes const * active_notes = 0) const {
280  return const_iterator (*this, t, force_discrete, f, active_notes);
281  }
282 
283  const const_iterator& end() const { return _end_iter; }
284 
285  void dump (std::ostream&, const_iterator x, uint32_t limit = 0) const;
286 
287  // CONST iterator implementations (x3)
288  typename Notes::const_iterator note_lower_bound (Time t) const;
289  typename PatchChanges::const_iterator patch_change_lower_bound (Time t) const;
290  typename SysExes::const_iterator sysex_lower_bound (Time t) const;
291 
292  // NON-CONST iterator implementations (x3)
293  typename Notes::iterator note_lower_bound (Time t);
294  typename PatchChanges::iterator patch_change_lower_bound (Time t);
295  typename SysExes::iterator sysex_lower_bound (Time t);
296 
297  bool control_to_midi_event(std::shared_ptr< Event<Time> >& ev,
298  const ControlIterator& iter) const;
299 
300  bool edited() const { return _edited; }
301  void set_edited(bool yn) { _edited = yn; }
302 
303  bool contains (const NotePtr& ev) const;
304 
305  bool add_note_unlocked (const NotePtr note, void* arg = 0);
307 
310 
313 
314  uint8_t lowest_note() const { return _lowest_note; }
315  uint8_t highest_note() const { return _highest_note; }
316 
317  Time duration() const { return _duration; }
318  void set_duration (Time const &);
319 
320 protected:
321  bool _edited;
324  mutable Glib::Threads::RWLock _lock;
325  bool _writing;
326 
327  virtual int resolve_overlaps_unlocked (const NotePtr, void* /* arg */ = 0) {
328  return 0;
329  }
330 
331  typedef std::multiset<NotePtr, NoteNumberComparator> Pitches;
332  inline Pitches& pitches(uint8_t chan) { return _pitches[chan&0xf]; }
333  inline const Pitches& pitches(uint8_t chan) const { return _pitches[chan&0xf]; }
334 
335  virtual void control_list_marked_dirty ();
336 
337 private:
338  friend class const_iterator;
339 
340  bool contains_unlocked (const NotePtr& ev) const;
341 
344  void append_control_unlocked(const Parameter& param, Time time, double value, Evoral::event_id_t);
347 
348  void get_notes_by_pitch (Notes&, NoteOperator, uint8_t val, int chan_mask = 0) const;
349  void get_notes_by_velocity (Notes&, NoteOperator, uint8_t val, int chan_mask = 0) const;
350 
352 
353  Notes _notes; // notes indexed by time
354  Pitches _pitches[16]; // notes indexed by channel+pitch
357 
358  typedef std::multiset<NotePtr, EarlierNoteComparator> WriteNotes;
359  WriteNotes _write_notes[16];
360 
365  int _bank[16];
366 
369 
370  uint8_t _lowest_note;
371  uint8_t _highest_note;
372 
373  Time _duration;
375 
376  void update_duration_unlocked (Time const &, bool can_shorten = false);
377 };
378 
379 
380 } // namespace Evoral
381 
382 template<typename Time> /*LIBEVORAL_API*/ std::ostream& operator<<(std::ostream& o, const Evoral::Sequence<Time>& s) { s.dump (o); return o; }
383 
384 
385 #endif // EVORAL_SEQUENCE_HPP
std::ostream & operator<<(std::ostream &o, const Evoral::Sequence< Time > &s)
Definition: Sequence.h:382
std::shared_ptr< const ControlList > list
Definition: Sequence.h:59
Temporal::timepos_t x
Definition: Sequence.h:60
ControlIterator(std::shared_ptr< const ControlList > al, Temporal::timepos_t const &ax, double ay)
Definition: Sequence.h:53
virtual bool controls_empty() const
Definition: ControlSet.h:69
Time time() const
Definition: Note.h:61
const Event< Time > & operator*() const
Definition: Sequence.h:236
void get_active_notes(WeakActiveNotes &) const
const_iterator & operator=(const const_iterator &other)
ControlIterators _control_iters
Definition: Sequence.h:270
Time choose_next(Time earliest_t)
const Sequence< Time > * _seq
Definition: Sequence.h:257
PatchChanges::const_iterator _patch_change_iter
Definition: Sequence.h:269
SysExes::const_iterator _sysex_iter
Definition: Sequence.h:268
bool operator==(const const_iterator &other) const
Sequence::ReadLock _lock
Definition: Sequence.h:266
std::vector< ControlIterator > ControlIterators
Definition: Sequence.h:254
const std::shared_ptr< const Event< Time > > operator->() const
Definition: Sequence.h:237
const const_iterator & operator++()
Notes::const_iterator _note_iter
Definition: Sequence.h:267
bool operator!=(const const_iterator &other) const
Definition: Sequence.h:242
ControlIterators::iterator _control_iter
Definition: Sequence.h:271
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:258
PatchChanges::const_iterator patch_change_lower_bound(Time t) const
void set_edited(bool yn)
Definition: Sequence.h:301
std::shared_ptr< const Event< Time > > constSysExPtr
Definition: Sequence.h:193
bool overlapping_pitches_accepted() const
Definition: Sequence.h:185
bool empty() const
Definition: Sequence.h:118
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:275
OverlapPitchResolution _overlap_pitch_resolution
Definition: Sequence.h:323
bool add_note_unlocked(const NotePtr note, void *arg=0)
std::multiset< NotePtr, EarlierNoteComparator > WriteNotes
Definition: Sequence.h:358
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:91
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:120
const Pitches & pitches(uint8_t chan) const
Definition: Sequence.h:333
size_t n_notes() const
Definition: Sequence.h:117
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:205
bool _overlapping_pitches_accepted
Definition: Sequence.h:322
const PatchChanges & patch_changes() const
Definition: Sequence.h:216
void get_notes(Notes &, NoteOperator, uint8_t val, int chan_mask=0) const
bool writing() const
Definition: Sequence.h:103
const const_iterator _end_iter
Definition: Sequence.h:367
OverlapPitchResolution overlap_pitch_resolution() const
Definition: Sequence.h:187
std::priority_queue< NotePtr, std::deque< NotePtr >, LaterNoteEndComparator > ActiveNotes
Definition: Sequence.h:219
std::shared_ptr< const PatchChange< Time > > constPatchChangePtr
Definition: Sequence.h:206
uint8_t highest_note() const
Definition: Sequence.h:315
Notes::iterator note_lower_bound(Time t)
const SysExes & sysexes() const
Definition: Sequence.h:203
virtual ReadLock read_lock() const
Definition: Sequence.h:97
PatchChanges & patch_changes()
Definition: Sequence.h:215
const const_iterator & end() const
Definition: Sequence.h:283
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:356
void end_write(StuckNoteOption, Time when=Time())
void remove_overlapping_notes()
std::multiset< SysExPtr, EarlierSysExComparator > SysExes
Definition: Sequence.h:201
PatchChanges::iterator patch_change_lower_bound(Time t)
@ VelocityGreaterThanOrEqual
Definition: Sequence.h:171
@ VelocityLessThanOrEqual
Definition: Sequence.h:169
@ PitchGreaterThanOrEqual
Definition: Sequence.h:166
void overlapping_pitches_accepted(bool yn)
Definition: Sequence.h:186
void add_sysex_unlocked(const SysExPtr)
void trim_overlapping_notes()
bool contains(const NotePtr &ev) const
SysExes & sysexes()
Definition: Sequence.h:202
std::multiset< NotePtr, NoteNumberComparator > Pitches
Definition: Sequence.h:331
virtual WriteLock write_lock()
Definition: Sequence.h:98
uint8_t lowest_note() const
Definition: Sequence.h:314
bool control_to_midi_event(std::shared_ptr< Event< Time > > &ev, const ControlIterator &iter) const
const Notes & notes() const
Definition: Sequence.h:159
Sequence(const Sequence< Time > &other)
bool _explicit_duration
Definition: Sequence.h:374
SysExes _sysexes
Definition: Sequence.h:355
std::multiset< NotePtr, EarlierNoteComparator > Notes
Definition: Sequence.h:157
std::shared_ptr< Glib::Threads::RWLock::ReaderLock > ReadLock
Definition: Sequence.h:94
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:92
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
Glib::Threads::RWLock _lock
Definition: Sequence.h:324
void remove_sysex_unlocked(const SysExPtr)
const TypeMap & type_map() const
Definition: Sequence.h:115
void append_patch_change_unlocked(const PatchChange< Time > &, Evoral::event_id_t)
uint8_t _lowest_note
Definition: Sequence.h:370
Time duration() const
Definition: Sequence.h:317
const TypeMap & _type_map
Definition: Sequence.h:351
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:192
std::shared_ptr< Evoral::Note< Time > > NotePtr
Definition: Sequence.h:89
Notes & notes()
Definition: Sequence.h:158
std::weak_ptr< Evoral::Note< Time > > WeakNotePtr
Definition: Sequence.h:90
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:371
bool edited() const
Definition: Sequence.h:300
void set_overlap_pitch_resolution(OverlapPitchResolution opr)
Pitches & pitches(uint8_t chan)
Definition: Sequence.h:332
virtual void control_list_marked_dirty()
void add_patch_change_unlocked(const PatchChangePtr)
std::multiset< PatchChangePtr, EarlierPatchChangeComparator > PatchChanges
Definition: Sequence.h:214
std::shared_ptr< WriteLockImpl > WriteLock
Definition: Sequence.h:95
virtual int resolve_overlaps_unlocked(const NotePtr, void *=0)
Definition: Sequence.h:327
#define LIBEVORAL_API
Definition: editor.h:86
int32_t event_id_t
DebugBits Threads
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:133
bool operator()(const std::shared_ptr< const Note< Time > > a, const std::shared_ptr< const Note< Time > > b) const
Definition: Sequence.h:151
bool operator()(const std::shared_ptr< const Note< Time > > a, const std::shared_ptr< const Note< Time > > b) const
Definition: Sequence.h:126
Glib::Threads::Mutex::Lock * control_lock
Definition: Sequence.h:84
WriteLockImpl(Glib::Threads::RWLock &s, Glib::Threads::Mutex &c)
Definition: Sequence.h:76
Glib::Threads::RWLock::WriterLock * sequence_lock
Definition: Sequence.h:83