rect->property_x2() = xend;
ARDOUR::BeatsFramesConverter tconv(_trackview.session(), region->position());
+ const MidiModel::TimeType start_beats = tconv.from(start);
/* draw events */
MidiRegionView* mrv = (MidiRegionView*)iter->second;
- // FIXME: this is offensively slow (linear search)
- for (MidiModel::Notes::const_iterator i = data->notes().begin();
+ for (MidiModel::Notes::const_iterator i = data->note_lower_bound(start_beats);
i != data->notes().end(); ++i) {
const boost::shared_ptr<MidiRegionView::NoteType>& note = *i;
const_iterator begin(Time t=0) const { return const_iterator(*this, t); }
const const_iterator& end() const { return _end_iter; }
+ typename Notes::const_iterator note_lower_bound (Time t) const;
+
bool control_to_midi_event(boost::shared_ptr< Event<Time> >& ev,
const ControlIterator& iter) const;
seq.read_lock();
- // Find first note which begins after t
- boost::shared_ptr< Note<Time> > search_note(new Note<Time>(0, t, 0, 0, 0));
- _note_iter = seq.notes().lower_bound(search_note);
- assert(_note_iter == seq.notes().end() || (*_note_iter)->time() >= t);
+ // Find first note which begins at or after t
+ _note_iter = seq.note_lower_bound(t);
- // Find first sysex event after t
+ // Find first sysex event at or after t
for (typename Sequence<Time>::SysExes::const_iterator i = seq.sysexes().begin();
i != seq.sysexes().end(); ++i) {
if ((*i)->time() >= t) {
_notes = n;
}
+/** Return the earliest note with time >= t */
+template<typename Time>
+typename Sequence<Time>::Notes::const_iterator
+Sequence<Time>::note_lower_bound (Time t) const
+{
+ boost::shared_ptr< Note<Time> > search_note(new Note<Time>(0, t, 0, 0, 0));
+ typename Sequence<Time>::Notes::const_iterator i = _notes.lower_bound(search_note);
+ assert(i == _notes.end() || (*i)->time() >= t);
+ return i;
+}
+
template class Sequence<Evoral::MusicalTime>;
} // namespace Evoral