Ardour  9.5-107-gea8286bce0
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 
188  FirstOnFirstOff
189  };
190 
191  bool overlapping_pitches_accepted() const { return _overlapping_pitches_accepted; }
192  void overlapping_pitches_accepted(bool yn) { _overlapping_pitches_accepted = yn; }
193  OverlapPitchResolution overlap_pitch_resolution() const { return _overlap_pitch_resolution; }
195 
196  void set_notes (const typename Sequence<Time>::Notes& n);
197 
198  typedef std::shared_ptr< Event<Time> > SysExPtr;
199  typedef std::shared_ptr<const Event<Time> > constSysExPtr;
200 
202  inline bool operator() (constSysExPtr a, constSysExPtr b) const {
203  return a->time() < b->time();
204  }
205  };
206 
207  typedef std::multiset<SysExPtr, EarlierSysExComparator> SysExes;
208  inline SysExes& sysexes() { return _sysexes; }
209  inline const SysExes& sysexes() const { return _sysexes; }
210 
211  typedef std::shared_ptr<PatchChange<Time> > PatchChangePtr;
212  typedef std::shared_ptr<const PatchChange<Time> > constPatchChangePtr;
213 
215  inline bool operator() (constPatchChangePtr a, constPatchChangePtr b) const {
216  return a->time() < b->time();
217  }
218  };
219 
220  typedef std::multiset<PatchChangePtr, EarlierPatchChangeComparator> PatchChanges;
221  inline PatchChanges& patch_changes () { return _patch_changes; }
222  inline const PatchChanges& patch_changes () const { return _patch_changes; }
223 
224 private:
225  typedef std::priority_queue<NotePtr, std::deque<NotePtr>, LaterNoteEndComparator> ActiveNotes;
226 public:
227 
230  public:
233  Time t,
234  bool force_discrete,
235  std::set<Evoral::Parameter> const & filtered,
236  WeakActiveNotes const* active_notes = 0);
237 
238  inline bool valid() const { return !_is_end && _event; }
239 
240  void invalidate (bool preserve_notes);
241 
242  const Event<Time>& operator*() const { return *_event; }
243  const std::shared_ptr< const Event<Time> > operator->() const { return _event; }
244 
245  const const_iterator& operator++(); // prefix only
246 
247  bool operator==(const const_iterator& other) const;
248  bool operator!=(const const_iterator& other) const { return ! operator==(other); }
249 
251 
253 
254  private:
255  friend class Sequence<Time>;
256 
257  Time choose_next(Time earliest_t);
258  void set_event();
259 
260  typedef std::vector<ControlIterator> ControlIterators;
261  enum MIDIMessageType { NIL, NOTE_ON, NOTE_OFF, CONTROL, SYSEX, PATCH_CHANGE };
262 
264  std::shared_ptr< Event<Time> > _event;
271  bool _is_end;
273  typename Notes::const_iterator _note_iter;
274  typename SysExes::const_iterator _sysex_iter;
275  typename PatchChanges::const_iterator _patch_change_iter;
277  ControlIterators::iterator _control_iter;
279  };
280 
282  Time t = Time(),
283  bool force_discrete = false,
284  const std::set<Evoral::Parameter>& f = std::set<Evoral::Parameter>(),
285  WeakActiveNotes const * active_notes = 0) const {
286  return const_iterator (*this, t, force_discrete, f, active_notes);
287  }
288 
289  const const_iterator& end() const { return _end_iter; }
290 
291  void dump (std::ostream&, const_iterator x, uint32_t limit = 0) const;
292 
293  // CONST iterator implementations (x3)
294  typename Notes::const_iterator note_lower_bound (Time t) const;
295  typename PatchChanges::const_iterator patch_change_lower_bound (Time t) const;
296  typename SysExes::const_iterator sysex_lower_bound (Time t) const;
297 
298  // NON-CONST iterator implementations (x3)
299  typename Notes::iterator note_lower_bound (Time t);
300  typename PatchChanges::iterator patch_change_lower_bound (Time t);
301  typename SysExes::iterator sysex_lower_bound (Time t);
302 
303  bool control_to_midi_event(std::shared_ptr< Event<Time> >& ev,
304  const ControlIterator& iter) const;
305 
306  bool edited() const { return _edited; }
307  void set_edited(bool yn) { _edited = yn; }
308 
309  bool contains (const NotePtr& ev) const;
310 
311  bool add_note_unlocked (const NotePtr note, void* arg = 0);
313 
316 
319 
320  uint8_t lowest_note() const { return _lowest_note; }
321  uint8_t highest_note() const { return _highest_note; }
322 
323  uint16_t channels_present () const { return _channels_present; }
324 
325  Time duration() const { return _duration; }
326  void set_duration (Time const &);
327 
328  void shift (Time const &);
329 
330 protected:
331  bool _edited;
335  bool _writing;
336 
337  virtual int resolve_overlaps_unlocked (const NotePtr, void* /* arg */ = 0) {
338  return 0;
339  }
340 
341  typedef std::multiset<NotePtr, NoteNumberComparator> Pitches;
342  inline Pitches& pitches(uint8_t chan) { return _pitches[chan&0xf]; }
343  inline const Pitches& pitches(uint8_t chan) const { return _pitches[chan&0xf]; }
344 
345  virtual void control_list_marked_dirty ();
346 
347 private:
348  friend class const_iterator;
349 
350  bool contains_unlocked (const NotePtr& ev) const;
351 
354  void append_control_unlocked(const Parameter& param, Time time, double value, Evoral::event_id_t);
357 
358  void get_notes_by_pitch (Notes&, NoteOperator, uint8_t val, int chan_mask = 0) const;
359  void get_notes_by_velocity (Notes&, NoteOperator, uint8_t val, int chan_mask = 0) const;
360 
362 
363  Notes _notes; // notes indexed by time
364  Pitches _pitches[16]; // notes indexed by channel+pitch
367 
368  typedef std::multiset<NotePtr, EarlierNoteComparator> WriteNotes;
369  WriteNotes _write_notes[16];
370 
375  int _bank[16];
376 
379 
380  uint8_t _lowest_note;
381  uint8_t _highest_note;
383 
384  Time _duration;
386 
387  void update_duration_unlocked (Time const &, bool can_shorten = false);
388 };
389 
390 
391 } // namespace Evoral
392 
393 template<typename Time> /*LIBEVORAL_API*/ std::ostream& operator<<(std::ostream& o, const Evoral::Sequence<Time>& s) { s.dump (o); return o; }
394 
395 
396 #endif // EVORAL_SEQUENCE_HPP
std::ostream & operator<<(std::ostream &o, const Evoral::Sequence< Time > &s)
Definition: Sequence.h:393
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:242
void get_active_notes(WeakActiveNotes &) const
const_iterator & operator=(const const_iterator &other)
ControlIterators _control_iters
Definition: Sequence.h:276
Time choose_next(Time earliest_t)
const Sequence< Time > * _seq
Definition: Sequence.h:263
PatchChanges::const_iterator _patch_change_iter
Definition: Sequence.h:275
SysExes::const_iterator _sysex_iter
Definition: Sequence.h:274
bool operator==(const const_iterator &other) const
Sequence::ReadLock _lock
Definition: Sequence.h:272
std::vector< ControlIterator > ControlIterators
Definition: Sequence.h:260
const std::shared_ptr< const Event< Time > > operator->() const
Definition: Sequence.h:243
const const_iterator & operator++()
Notes::const_iterator _note_iter
Definition: Sequence.h:273
bool operator!=(const const_iterator &other) const
Definition: Sequence.h:248
ControlIterators::iterator _control_iter
Definition: Sequence.h:277
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:264
PatchChanges::const_iterator patch_change_lower_bound(Time t) const
void set_edited(bool yn)
Definition: Sequence.h:307
std::shared_ptr< const Event< Time > > constSysExPtr
Definition: Sequence.h:199
bool overlapping_pitches_accepted() const
Definition: Sequence.h:191
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:281
std::shared_ptr< PBD::RWLock::ReaderLock > ReadLock
Definition: Sequence.h:95
OverlapPitchResolution _overlap_pitch_resolution
Definition: Sequence.h:333
bool add_note_unlocked(const NotePtr note, void *arg=0)
std::multiset< NotePtr, EarlierNoteComparator > WriteNotes
Definition: Sequence.h:368
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:343
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:211
bool _overlapping_pitches_accepted
Definition: Sequence.h:332
const PatchChanges & patch_changes() const
Definition: Sequence.h:222
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:377
OverlapPitchResolution overlap_pitch_resolution() const
Definition: Sequence.h:193
std::priority_queue< NotePtr, std::deque< NotePtr >, LaterNoteEndComparator > ActiveNotes
Definition: Sequence.h:225
std::shared_ptr< const PatchChange< Time > > constPatchChangePtr
Definition: Sequence.h:212
uint8_t highest_note() const
Definition: Sequence.h:321
Notes::iterator note_lower_bound(Time t)
const SysExes & sysexes() const
Definition: Sequence.h:209
virtual ReadLock read_lock() const
Definition: Sequence.h:98
PatchChanges & patch_changes()
Definition: Sequence.h:221
const const_iterator & end() const
Definition: Sequence.h:289
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:366
void end_write(StuckNoteOption, Time when=Time())
std::multiset< SysExPtr, EarlierSysExComparator > SysExes
Definition: Sequence.h:207
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:192
void add_sysex_unlocked(const SysExPtr)
bool contains(const NotePtr &ev) const
SysExes & sysexes()
Definition: Sequence.h:208
std::multiset< NotePtr, NoteNumberComparator > Pitches
Definition: Sequence.h:341
virtual WriteLock write_lock()
Definition: Sequence.h:99
uint8_t lowest_note() const
Definition: Sequence.h:320
bool control_to_midi_event(std::shared_ptr< Event< Time > > &ev, const ControlIterator &iter) const
uint16_t channels_present() const
Definition: Sequence.h:323
const Notes & notes() const
Definition: Sequence.h:169
Sequence(const Sequence< Time > &other)
bool _explicit_duration
Definition: Sequence.h:385
SysExes _sysexes
Definition: Sequence.h:365
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 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:380
Time duration() const
Definition: Sequence.h:325
const TypeMap & _type_map
Definition: Sequence.h:361
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:198
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:381
bool edited() const
Definition: Sequence.h:306
void set_overlap_pitch_resolution(OverlapPitchResolution opr)
Pitches & pitches(uint8_t chan)
Definition: Sequence.h:342
virtual void control_list_marked_dirty()
void add_patch_change_unlocked(const PatchChangePtr)
PBD::RWLock _lock
Definition: Sequence.h:334
std::multiset< PatchChangePtr, EarlierPatchChangeComparator > PatchChanges
Definition: Sequence.h:220
uint16_t _channels_present
Definition: Sequence.h:382
std::shared_ptr< WriteLockImpl > WriteLock
Definition: Sequence.h:96
virtual int resolve_overlaps_unlocked(const NotePtr, void *=0)
Definition: Sequence.h:337
#define LIBEVORAL_API
Definition: editor.h:86
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