61 template<
typename Time>
65 , _active_patch_change_message (0)
68 , _control_iter(_control_iters.end())
69 , _force_discrete(false)
74 template<
typename Time>
78 const std::set<Evoral::Parameter>& filtered,
79 const std::set<WeakNotePtr>* active_notes)
81 , _active_patch_change_message (0)
83 , _is_end((t == DBL_MAX) || seq.
empty())
87 , _control_iter(_control_iters.
end())
88 , _force_discrete (force_discrete)
100 for (
typename std::set<WeakNotePtr>::const_iterator i = active_notes->begin();
101 i != active_notes->end(); ++i) {
103 if (note && note->time() <= t && note->end_time() > t) {
114 i != seq.
sysexes().end(); ++i) {
115 if ((*i)->time() >= t) {
124 if ((*i)->time() >= t) {
134 size_t earliest_control_index = 0;
135 double earliest_control_x = DBL_MAX;
136 for (Controls::const_iterator i = seq.
_controls.begin(); i != seq.
_controls.end(); ++i) {
138 if (filtered.find (i->first) != filtered.end()) {
147 ret = i->second->list()->rt_safe_earliest_event_discrete_unlocked (t.to_double(), x, y,
true);
149 ret = i->second->list()->rt_safe_earliest_event_unlocked(t.to_double(), x, y,
true);
153 i->first.id(), i->second->list()->size(), t));
160 if (y < desc.lower || y > desc.
upper) {
161 cerr <<
"ERROR: Controller value " << y
162 <<
" out of range [" << desc.
lower <<
"," << desc.
upper
163 <<
"], event ignored" << endl;
173 if (x < earliest_control_x) {
174 earliest_control_x = x;
204 (
int)
_event->event_type(),
210 template<
typename Time>
214 while (!_active_notes.empty()) {
216 notes->insert(_active_notes.top());
223 _note_iter = _seq->notes().end();
224 _sysex_iter = _seq->sysexes().end();
225 _patch_change_iter = _seq->patch_changes().end();
226 _active_patch_change_message = 0;
228 _control_iters.clear();
229 _control_iter = _control_iters.end();
233 template<
typename Time>
240 if (_note_iter != _seq->notes().end()) {
242 earliest_t = (*_note_iter)->time();
246 if ((!_active_notes.empty())) {
247 if (_type == NIL || _active_notes.top()->end_time() <= earliest_t) {
249 earliest_t = _active_notes.top()->end_time();
254 if (_control_iter != _control_iters.end() &&
255 _control_iter->list && _control_iter->x != DBL_MAX) {
256 if (_type == NIL || _control_iter->x < earliest_t.to_double()) {
258 earliest_t = Time(_control_iter->x);
263 if (_sysex_iter != _seq->sysexes().end()) {
264 if (_type == NIL || (*_sysex_iter)->time() < earliest_t) {
266 earliest_t = (*_sysex_iter)->time();
271 if (_patch_change_iter != _seq->patch_changes().end()) {
272 if (_type == NIL || (*_patch_change_iter)->time() < earliest_t) {
273 _type = PATCH_CHANGE;
274 earliest_t = (*_patch_change_iter)->time();
280 template<
typename Time>
287 *_event = (*_note_iter)->on_event();
288 _active_notes.push(*_note_iter);
292 assert(!_active_notes.empty());
293 *_event = _active_notes.top()->off_event();
298 *_event = *(*_sysex_iter);
302 _seq->control_to_midi_event(_event, *_control_iter);
306 *_event = (*_patch_change_iter)->message (_active_patch_change_message);
313 if (_type == NIL || !_event || _event->size() == 0) {
322 template<
typename Time>
327 throw std::logic_error(
"Attempt to iterate past end of Sequence");
330 assert(_event && _event->buffer() && _event->size() > 0);
336 || ev.is_pgm_change()
337 || ev.is_pitch_bender()
338 || ev.is_channel_pressure()
339 || ev.is_sysex()) ) {
340 cerr <<
"WARNING: Unknown event (type " << _type <<
"): " << hex
341 << int(ev.buffer()[0]) <<
int(ev.buffer()[1]) <<
int(ev.buffer()[2]) << endl;
359 ret = _control_iter->list->rt_safe_earliest_event_discrete_unlocked (
360 _control_iter->x, x, y,
false);
362 ret = _control_iter->list->rt_safe_earliest_event_linear_unlocked (
365 assert(!ret || x > _control_iter->x);
367 _control_iter->x = x;
368 _control_iter->y = y;
370 _control_iter->list.reset();
371 _control_iter->x = DBL_MAX;
372 _control_iter->y = DBL_MAX;
376 _control_iter = _control_iters.begin();
377 for (ControlIterators::iterator i = _control_iters.begin();
378 i != _control_iters.end(); ++i) {
379 if (i->x < _control_iter->x) {
388 ++_active_patch_change_message;
389 if (_active_patch_change_message == (*_patch_change_iter)->messages()) {
390 ++_patch_change_iter;
391 _active_patch_change_message = 0;
399 choose_next(std::numeric_limits<Time>::max());
404 assert(_is_end || (_event->size() > 0 && _event->buffer() && _event->buffer()[0] !=
'\0'));
409 template<
typename Time>
413 if (_seq != other.
_seq) {
415 }
else if (_is_end || other.
_is_end) {
416 return (_is_end == other.
_is_end);
417 }
else if (_type != other.
_type) {
420 return (_event == other.
_event);
424 template<
typename Time>
441 _lock = _seq->read_lock();
447 _control_iter = _control_iters.end();
450 _control_iter = _control_iters.begin() + index;
458 template<
typename Time>
474 for (
int i = 0; i < 16; ++i) {
479 template<
typename Time>
483 , _overlapping_pitches_accepted (other._overlapping_pitches_accepted)
484 , _overlap_pitch_resolution (other._overlap_pitch_resolution)
486 , _type_map(other._type_map)
488 , _percussive(other._percussive)
489 , _lowest_note(other._lowest_note)
490 , _highest_note(other._highest_note)
492 for (
typename Notes::const_iterator i = other.
_notes.begin(); i != other.
_notes.end(); ++i) {
497 for (
typename SysExes::const_iterator i = other.
_sysexes.begin(); i != other.
_sysexes.end(); ++i) {
507 for (
int i = 0; i < 16; ++i) {
521 template<
typename Time>
527 assert(iter.
list.get());
528 const uint32_t event_type = iter.
list->parameter().type();
535 uint8_t midi_type = _type_map.parameter_midi_type(iter.
list->parameter());
536 ev->set_event_type(_type_map.midi_event_type(midi_type));
539 assert(iter.
list.get());
540 assert(iter.
list->parameter().channel() < 16);
541 assert(iter.
list->parameter().id() <= INT8_MAX);
542 assert(iter.
y <= INT8_MAX);
544 ev->set_time(Time(iter.
x));
547 ev->buffer()[1] = (uint8_t)iter.
list->parameter().id();
548 ev->buffer()[2] = (uint8_t)iter.
y;
552 assert(iter.
list.get());
553 assert(iter.
list->parameter().channel() < 16);
554 assert(iter.
y <= INT8_MAX);
556 ev->set_time(Time(iter.
x));
559 ev->buffer()[1] = (uint8_t)iter.
y;
563 assert(iter.
list.get());
564 assert(iter.
list->parameter().channel() < 16);
565 assert(iter.
y < (1<<14));
567 ev->set_time(Time(iter.
x));
570 ev->buffer()[1] = uint16_t(iter.
y) & 0x7F;
571 ev->buffer()[2] = (uint16_t(iter.
y) >> 7) & 0x7F;
575 assert(iter.
list.get());
576 assert(iter.
list->parameter().channel() < 16);
577 assert(iter.
y <= INT8_MAX);
579 ev->set_time(Time(iter.
x));
582 ev->buffer()[1] = (uint8_t)iter.
y;
594 template<
typename Time>
600 for (Controls::iterator li = _controls.begin(); li != _controls.end(); ++li)
601 li->second->list()->clear();
611 template<
typename Time>
618 for (
int i = 0; i < 16; ++i) {
619 _write_notes[i].clear();
629 template<
typename Time>
641 for (
typename Notes::iterator n = _notes.begin(); n != _notes.end() ;) {
642 typename Notes::iterator next = n;
645 if (!(*n)->length()) {
649 case DeleteStuckNotes:
650 cerr <<
"WARNING: Stuck note lost: " << (*n)->note() << endl;
653 case ResolveStuckNotes:
654 if (when <= (*n)->time()) {
655 cerr <<
"WARNING: Stuck note resolution - end time @ "
656 << when <<
" is before note on: " << (**n) << endl;
659 (*n)->set_length (when - (*n)->time());
660 cerr <<
"WARNING: resolved note-on with no note-off to generate " << (**n) << endl;
669 for (
int i = 0; i < 16; ++i) {
670 _write_notes[i].clear();
677 template<
typename Time>
686 if (resolve_overlaps_unlocked (note, arg)) {
691 if (note->id() < 0) {
695 if (note->note() < _lowest_note)
696 _lowest_note = note->note();
697 if (note->note() > _highest_note)
698 _highest_note = note->note();
700 _notes.insert (note);
701 _pitches[note->channel()].insert (note);
708 template<
typename Time>
713 bool id_matched =
false;
726 for (i = note_lower_bound(note->time()); i != _notes.
end() && (*i)->time() == note->time(); ++i) {
733 if (note->note() == _lowest_note || note->note() == _highest_note) {
739 if ((*ii)->note() < _lowest_note)
740 _lowest_note = (*ii)->note();
741 if ((*ii)->note() > _highest_note)
742 _highest_note = (*ii)->note();
766 for (i = _notes.
begin(); i != _notes.
end(); ++i) {
768 if ((*i)->id() == note->id()) {
773 if (note->note() == _lowest_note || note->note() == _highest_note) {
779 if ((*ii)->note() < _lowest_note)
780 _lowest_note = (*ii)->note();
781 if ((*ii)->note() > _highest_note)
782 _highest_note = (*ii)->note();
795 Pitches& p (pitches (note->channel()));
797 typename Pitches::iterator j;
807 for (j = p.begin(); j != p.end(); ++j) {
808 if ((*j)->id() == note->id()) {
823 for (j = p.lower_bound (search_note); j != p.end() && (*j)->note() == note->note(); ++j) {
840 cerr <<
"Unable to find note to erase matching " << *note.
get() <<
endmsg;
844 template<
typename Time>
850 while (i != _patch_changes.
end() && ((*i)->time() == p->time())) {
856 _patch_changes.erase (i);
863 template<
typename Time>
868 while (i != _sysexes.
end() && (*i)->time() == sysex->time()) {
887 template<
typename Time>
895 assert(_notes.empty() || ev.
time() >= (*_notes.rbegin())->time());
899 cerr <<
"WARNING: Sequence ignoring illegal MIDI event" << endl;
904 append_note_on_unlocked (ev, evid);
909 append_note_off_unlocked (ev);
911 append_sysex_unlocked(ev, evid);
915 _bank[ev.
channel()] &= ~(0x7f << 7);
921 }
else if (ev.
is_cc()) {
922 append_control_unlocked(
929 append_control_unlocked(
935 append_control_unlocked(
938 }
else if (!_type_map.type_is_midi(ev.
event_type())) {
939 printf(
"WARNING: Sequence: Unknown event type %X: ", ev.
event_type());
940 for (
size_t i=0; i < ev.
size(); ++i) {
941 printf(
"%X ", ev.
buffer()[i]);
945 printf(
"WARNING: Sequence: Unknown MIDI event type %X\n", ev.
type());
951 template<
typename Time>
960 if (ev.
note() > 127) {
963 }
else if (ev.
channel() >= 16) {
975 add_note_unlocked (note);
978 (
unsigned)(uint8_t)note->note(), note->channel()));
979 _write_notes[note->channel()].insert (note);
983 template<
typename Time>
992 if (ev.
note() > 127) {
995 }
else if (ev.
channel() >= 16) {
1002 bool resolved =
false;
1012 for (
typename WriteNotes::iterator n = _write_notes[ev.
channel()].begin(); n != _write_notes[ev.
channel()].end(); ) {
1014 typename WriteNotes::iterator tmp = n;
1018 if (ev.
note() == nn->note() && nn->channel() == ev.
channel()) {
1019 assert(ev.
time() >= nn->time());
1021 nn->set_length (ev.
time() - nn->time());
1022 nn->set_off_velocity (ev.
velocity());
1024 _write_notes[ev.
channel()].erase(n);
1034 cerr <<
this <<
" spurious note off chan " << (int)ev.
channel()
1035 <<
", note " << (int)ev.
note() <<
" @ " << ev.
time() << endl;
1039 template<
typename Time>
1044 this, _type_map.to_symbol(param), time, value, _controls.size()));
1046 c->
list()->add (time.to_double(), value);
1050 template<
typename Time>
1054 #ifdef DEBUG_SEQUENCE
1055 cerr <<
this <<
" SysEx @ " << ev.
time() <<
" \t= \t [ " << hex;
1056 for (
size_t i=0; i < ev.
size(); ++i) {
1057 cerr << int(ev.
buffer()[i]) <<
" ";
1058 } cerr <<
"]" << endl;
1063 _sysexes.insert(event);
1066 template<
typename Time>
1076 _patch_changes.insert (p);
1079 template<
typename Time>
1087 _patch_changes.insert (p);
1090 template<
typename Time>
1098 _sysexes.insert (s);
1101 template<
typename Time>
1106 return contains_unlocked (note);
1109 template<
typename Time>
1113 const Pitches& p (pitches (note->channel()));
1116 for (
typename Pitches::const_iterator i = p.lower_bound (search_note);
1117 i != p.end() && (*i)->note() == note->note(); ++i) {
1127 template<
typename Time>
1132 return overlaps_unlocked (note, without);
1135 template<
typename Time>
1139 Time sa = note->time();
1140 Time ea = note->end_time();
1142 const Pitches& p (pitches (note->channel()));
1145 for (
typename Pitches::const_iterator i = p.lower_bound (search_note);
1146 i != p.end() && (*i)->note() == note->note(); ++i) {
1148 if (without && (**i) == *without) {
1152 Time sb = (*i)->time();
1153 Time eb = (*i)->end_time();
1155 if (((sb > sa) && (eb <= ea)) ||
1156 ((eb >= sa) && (eb <= ea)) ||
1157 ((sb > sa) && (sb <= ea)) ||
1158 ((sa >= sb) && (sa <= eb) && (ea <= eb))) {
1166 template<
typename Time>
1176 template<
typename Time>
1182 assert(i == _notes.
end() || (*i)->time() >= t);
1187 template<
typename Time>
1193 assert (i == _patch_changes.
end() || (*i)->time() >= t);
1198 template<
typename Time>
1204 assert (i == _sysexes.
end() || (*i)->time() >= t);
1211 template<
typename Time>
1217 assert(i == _notes.
end() || (*i)->time() >= t);
1222 template<
typename Time>
1228 assert (i == _patch_changes.
end() || (*i)->time() >= t);
1233 template<
typename Time>
1239 assert (i == _sysexes.
end() || (*i)->time() >= t);
1243 template<
typename Time>
1250 case PitchLessThanOrEqual:
1252 case PitchGreaterThanOrEqual:
1253 get_notes_by_pitch (n, op, val, chan_mask);
1257 case VelocityLessThan:
1258 case VelocityLessThanOrEqual:
1259 case VelocityGreater:
1260 case VelocityGreaterThanOrEqual:
1261 get_notes_by_velocity (n, op, val, chan_mask);
1266 template<
typename Time>
1270 for (uint8_t c = 0; c < 16; ++c) {
1272 if (chan_mask != 0 && !((1<<c) & chan_mask)) {
1276 const Pitches& p (pitches (c));
1278 typename Pitches::const_iterator i;
1281 i = p.lower_bound (search_note);
1282 while (i != p.end() && (*i)->note() == val) {
1287 i = p.upper_bound (search_note);
1288 while (i != p.end() && (*i)->note() < val) {
1292 case PitchLessThanOrEqual:
1293 i = p.upper_bound (search_note);
1294 while (i != p.end() && (*i)->note() <= val) {
1299 i = p.lower_bound (search_note);
1300 while (i != p.end() && (*i)->note() > val) {
1304 case PitchGreaterThanOrEqual:
1305 i = p.lower_bound (search_note);
1306 while (i != p.end() && (*i)->note() >= val) {
1318 template<
typename Time>
1324 for (
typename Notes::const_iterator i = _notes.begin(); i != _notes.end(); ++i) {
1326 if (chan_mask != 0 && !((1<<((*i)->channel())) & chan_mask)) {
1332 if ((*i)->velocity() == val) {
1336 case VelocityLessThan:
1337 if ((*i)->velocity() < val) {
1341 case VelocityLessThanOrEqual:
1342 if ((*i)->velocity() <= val) {
1346 case VelocityGreater:
1347 if ((*i)->velocity() > val) {
1351 case VelocityGreaterThanOrEqual:
1352 if ((*i)->velocity() >= val) {
1364 template<
typename Time>
1368 _overlap_pitch_resolution = opr;
1373 template<
typename Time>
1380 template<
typename Time>
1385 str <<
"+++ dump\n";
1386 for (i = begin(); i != end(); ++i) {
1389 str <<
"--- dump\n";
const const_iterator & operator++()
bool is_pgm_change() const
EventType event_type() const
#define MIDI_CTL_MSB_BANK
std::multiset< NotePtr, EarlierNoteComparator > Notes
OverlapPitchResolution _overlap_pitch_resolution
void remove_sysex_unlocked(const SysExPtr)
float lower
Minimum value (in Hz, for frequencies)
bool overlaps_unlocked(const NotePtr &ev, const NotePtr &ignore_this_note) const
std::multiset< NotePtr, NoteNumberComparator > Pitches
uint8_t channel_pressure() const
#define MIDI_CTL_LSB_BANK
#define MIDI_CMD_CHANNEL_PRESSURE
static bool midi_event_is_valid(const uint8_t *buffer, size_t len)
uint8_t pitch_bender_lsb() const
void append_patch_change_unlocked(const PatchChange< Time > &, Evoral::event_id_t)
Time choose_next(Time earliest_t)
#define MIDI_CMD_PGM_CHANGE
boost::shared_ptr< Event< Time > > _event
SysExes::const_iterator sysex_lower_bound(Time t) const
PatchChanges _patch_changes
bool is_pitch_bender() const
void append_control_unlocked(const Parameter ¶m, Time time, double value, Evoral::event_id_t)
LIBPBD_API Transmitter error
LIBPBD_API Transmitter warning
const TypeMap & _type_map
std::ostream & endmsg(std::ostream &ostr)
LIBEVORAL_API uint64_t Sequence
bool contains_unlocked(const NotePtr &ev) const
void end_write(StuckNoteOption, Time when=Time())
const const_iterator _end_iter
PatchChanges & patch_changes()
void add_sysex_unlocked(const SysExPtr)
Notes::const_iterator _note_iter
void add_patch_change_unlocked(const PatchChangePtr)
float upper
Maximum value (in Hz, for frequencies)
const Sequence< Time > * _seq
ActiveNotes _active_notes
bool is_channel_pressure() const
bool control_to_midi_event(boost::shared_ptr< Event< Time > > &ev, const ControlIterator &iter) const
void set_overlap_pitch_resolution(OverlapPitchResolution opr)
void get_notes(Notes &, NoteOperator, uint8_t val, int chan_mask=0) const
uint8_t pgm_number() const
const const_iterator & end() const
Sequence(const TypeMap &type_map)
bool overlaps(const NotePtr &ev, const NotePtr &ignore_this_note) const
bool add_note_unlocked(const NotePtr note, void *arg=0)
void remove_patch_change_unlocked(const constPatchChangePtr)
void append_sysex_unlocked(const MIDIEvent< Time > &ev, Evoral::event_id_t)
SysExes::const_iterator _sysex_iter
virtual ReadLock read_lock() const
LIBEVORAL_API event_id_t next_event_id()
void dump(std::ostream &) const
#define DEBUG_TRACE(bits, str)
void get_notes_by_velocity(Notes &, NoteOperator, uint8_t val, int chan_mask=0) const
uint8_t cc_number() const
void remove_note_unlocked(const constNotePtr note)
bool operator==(const const_iterator &other) const
bool _overlapping_pitches_accepted
PatchChanges::const_iterator patch_change_lower_bound(Time t) const
void append_note_on_unlocked(const MIDIEvent< Time > &event, Evoral::event_id_t)
void append(const Event< Time > &ev, Evoral::event_id_t evid)
boost::shared_ptr< ControlList > list()
const_iterator begin(Time t=Time(), bool force_discrete=false, const std::set< Evoral::Parameter > &f=std::set< Evoral::Parameter >(), const std::set< WeakNotePtr > *active_notes=NULL) const
PatchChanges::const_iterator _patch_change_iter
ControlIterators::iterator _control_iter
Glib::Threads::RWLock _lock
boost::shared_ptr< const ControlList > list
void append_note_off_unlocked(const MIDIEvent< Time > &event)
bool contains(const NotePtr &ev) const
uint8_t pitch_bender_msb() const
const uint8_t * buffer() const
void invalidate(std::set< WeakNotePtr > *notes)
static double const time_between_interpolated_controller_outputs
const TypeMap & type_map() const
ControlIterators _control_iters
Notes::const_iterator note_lower_bound(Time t) const
void get_notes_by_pitch(Notes &, NoteOperator, uint8_t val, int chan_mask=0) const
void set_notes(const typename Sequence< Time >::Notes &n)
const_iterator & operator=(const const_iterator &other)
std::string string_compose(const std::string &fmt, const T1 &o1)
int _active_patch_change_message
virtual void control_list_marked_dirty()