/* This file is part of Evoral.
- * Copyright (C) 2008 Dave Robillard <http://drobilla.net>
+ * Copyright (C) 2008 David Robillard <http://drobilla.net>
* Copyright (C) 2000-2008 Paul Davis
*
* Evoral is free software; you can redistribute it and/or modify it under the
{
DEBUG_TRACE (DEBUG::Sequence, string_compose ("Created Iterator @ %1 (is end: %2)\n)", t, _is_end));
- if (!_is_end) {
- _lock = seq.read_lock();
- } else {
+ if (_is_end) {
return;
}
- typename Sequence<Time>::ReadLock lock(seq.read_lock());
+ _lock = seq.read_lock();
// Find first note which begins at or after t
_note_iter = seq.note_lower_bound(t);
_force_discrete = other._force_discrete;
_active_patch_change_message = other._active_patch_change_message;
- if (other._lock)
+ if (other._lock) {
_lock = _seq->read_lock();
- else
+ } else {
_lock.reset();
+ }
if (other._control_iter == other._control_iters.end()) {
_control_iter = _control_iters.end();
*/
template<typename Time>
void
-Sequence<Time>::end_write (bool delete_stuck)
+Sequence<Time>::end_write (StuckNoteOption option, Time when)
{
WriteLock lock(write_lock());
return;
}
- DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 : end_write (%2 notes)\n", this, _notes.size()));
+ DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 : end_write (%2 notes) delete stuck option %3 @ %4\n", this, _notes.size(), option, when));
+
+ if (!_percussive) {
- if (!_percussive && delete_stuck) {
for (typename Notes::iterator n = _notes.begin(); n != _notes.end() ;) {
typename Notes::iterator next = n;
++next;
if ((*n)->length() == 0) {
- cerr << "WARNING: Stuck note lost: " << (*n)->note() << endl;
- _notes.erase(n);
- }
-
+ switch (option) {
+ case Relax:
+ break;
+ case DeleteStuckNotes:
+ cerr << "WARNING: Stuck note lost: " << (*n)->note() << endl;
+ _notes.erase(n);
+ break;
+ case ResolveStuckNotes:
+ if (when <= (*n)->time()) {
+ cerr << "WARNING: Stuck note resolution - end time @ "
+ << when << " is before note on: " << (**n) << endl;
+ _notes.erase (*n);
+ } else {
+ (*n)->set_length (when - (*n)->time());
+ cerr << "WARNING: resolved note-on with no note-off to generate " << (**n) << endl;
+ }
+ break;
+ }
+ }
+
n = next;
}
}
for (int i = 0; i < 16; ++i) {
- if (!_write_notes[i].empty()) {
- cerr << "WARNING: Sequence<Time>::end_write: Channel " << i << " has "
- << _write_notes[i].size() << " stuck notes" << endl;
- }
_write_notes[i].clear();
}
_edited = true;
- return true;
+ return true;
}
template<typename Time>
++tmp;
if (*j == note) {
- DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1\terasing pitch %2 @ %3\n", this, (int)(*i)->note(), (*i)->time()));
+ DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1\terasing pitch %2 @ %3\n", this, (int)(*j)->note(), (*j)->time()));
p.erase (j);
}
}
if (!erased) {
- cerr << "Unable to find note to erase" << endl;
+ cerr << "Unable to find note to erase matching " << *note.get() << endl;
}
}
} else if (ev.is_cc() && (ev.cc_number() == MIDI_CTL_MSB_BANK || ev.cc_number() == MIDI_CTL_LSB_BANK)) {
/* note bank numbers in our _bank[] array, so that we can write an event when the program change arrives */
if (ev.cc_number() == MIDI_CTL_MSB_BANK) {
- _bank[ev.channel()] &= (0x7f << 7);
+ _bank[ev.channel()] &= ~(0x7f << 7);
_bank[ev.channel()] |= ev.cc_value() << 7;
} else {
- _bank[ev.channel()] &= 0x7f;
+ _bank[ev.channel()] &= ~0x7f;
_bank[ev.channel()] |= ev.cc_value();
}
} else if (ev.is_cc()) {
void
Sequence<Time>::append_note_off_unlocked (NotePtr note)
{
- DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 c=%2 note %3 on @ %4 v=%5\n",
+ DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 c=%2 note %3 OFF @ %4 v=%5\n",
this, (int)note->channel(),
(int)note->note(), note->time(), (int)note->velocity()));
assert(note->note() <= 127);
nn->set_off_velocity (note->velocity());
_write_notes[note->channel()].erase(n);
- DEBUG_TRACE (DEBUG::Sequence, string_compose ("resolved note, length: %1\n", note->length()));
+ DEBUG_TRACE (DEBUG::Sequence, string_compose ("resolved note @ %2 length: %1\n", nn->length(), nn->time()));
resolved = true;
break;
}
template class Sequence<Evoral::MusicalTime>;
+template<typename Time>
+void
+Sequence<Time>::dump (ostream& str) const
+{
+ Sequence<Time>::const_iterator i;
+ str << "+++ dump\n";
+ for (i = begin(); i != end(); ++i) {
+ str << *i << endl;
+ }
+ str << "--- dump\n";
+}
+
} // namespace Evoral