summaryrefslogtreecommitdiff
path: root/libs/ardour/midi_model.cc
diff options
context:
space:
mode:
authorHans Baier <hansfbaier@googlemail.com>2008-04-03 21:47:47 +0000
committerHans Baier <hansfbaier@googlemail.com>2008-04-03 21:47:47 +0000
commitfbfe9a798313fcb98b2d25df8d23c5c90c76a7ef (patch)
tree4d99a55cb00c85b67c2936cddce46ae411f44fe8 /libs/ardour/midi_model.cc
parent6554200e66cc243e92818e6e74d4647d1c34ae9c (diff)
* implemented editing velocities (http://tracker.ardour.org/view.php?id=2148)
* added MIDI panic button (http://tracker.ardour.org/view.php?id=2118) * bugfix: moving notes above midi 127 or below 0 does not wrap around anymore * bugfix: deadlock on editing notes after playback (http://tracker.ardour.org/view.php?id=2140) due to unbalanced lock acquire/release * bugfix: First note off lost in playback (http://tracker.ardour.org/view.php?id=2132) * bugfix: Last note off lost in saving MIDI files (http://tracker.ardour.org/view.php?id=2132) * bandaid fix for http://tracker.ardour.org/view.php?id=1985 (Cannot reopen session because jack ports are not unregistered on session close) * bandaid fix: replaced conf.CheckPKGExists ('\"slv2 >= 0.6.0\"') by conf.CheckPKGExists ('slv2') in SConstruct, because the former would fail, even if SLV 0.6.0 was installed * added/enabled debugging output for debugging MIDI model (might be removed later) git-svn-id: svn://localhost/ardour2/branches/3.0@3211 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/midi_model.cc')
-rw-r--r--libs/ardour/midi_model.cc69
1 files changed, 51 insertions, 18 deletions
diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc
index a49094df91..4aa229b450 100644
--- a/libs/ardour/midi_model.cc
+++ b/libs/ardour/midi_model.cc
@@ -36,6 +36,34 @@ using namespace std;
using namespace ARDOUR;
+void
+MidiModel::write_lock()
+{
+ _lock.writer_lock();
+ _automation_lock.lock();
+}
+
+void
+MidiModel::write_unlock()
+{
+ _lock.writer_unlock();
+ _automation_lock.unlock();
+}
+
+void
+MidiModel::read_lock() const
+{
+ _lock.reader_lock();
+ /*_automation_lock.lock();*/
+}
+
+void
+MidiModel::read_unlock() const
+{
+ _lock.reader_unlock();
+ /*_automation_lock.unlock();*/
+}
+
// Read iterator (const_iterator)
MidiModel::const_iterator::const_iterator(const MidiModel& model, double t)
@@ -51,7 +79,7 @@ MidiModel::const_iterator::const_iterator(const MidiModel& model, double t)
model.read_lock();
_note_iter = model.notes().end();
-
+ // find first note which begins after t
for (MidiModel::Notes::const_iterator i = model.notes().begin(); i != model.notes().end(); ++i) {
if ((*i)->time() >= t) {
_note_iter = i;
@@ -95,6 +123,7 @@ MidiModel::const_iterator::const_iterator(const MidiModel& model, double t)
if (_note_iter != model.notes().end()) {
_event = MIDI::Event((*_note_iter)->on_event(), false);
_active_notes.push(*_note_iter);
+ cerr << " new const iterator: size active notes: " << _active_notes.size() << " is empty: " << _active_notes.empty() << endl;
++_note_iter;
}
@@ -106,19 +135,22 @@ MidiModel::const_iterator::const_iterator(const MidiModel& model, double t)
if (_event.size() == 0) {
//cerr << "Created MIDI iterator @ " << t << " is at end." << endl;
_is_end = true;
+ if(_locked) {
_model->read_unlock();
_locked = false;
- } /*else {
+ }
+ } else {
printf("MIDI Iterator = %X @ %lf\n", _event.type(), _event.time());
- }*/
+}
}
MidiModel::const_iterator::~const_iterator()
{
- if (_locked)
+ if (_locked) {
_model->read_unlock();
}
+}
const MidiModel::const_iterator&
@@ -168,6 +200,7 @@ MidiModel::const_iterator::operator++()
t = (*_note_iter)->time();
}
+ cerr << " operator++ before test: size active notes: " << _active_notes.size() << " is empty: " << _active_notes.empty() << endl;
// Use the next earliest note off iff it's earlier than the note on
if (_model->note_mode() == Sustained && (! _active_notes.empty())) {
if (type == NIL || _active_notes.top()->end_time() <= (*_note_iter)->time()) {
@@ -182,22 +215,20 @@ MidiModel::const_iterator::operator++()
type = CC;
if (type == NOTE_ON) {
- //cerr << "********** MIDI Iterator = note on" << endl;
+ cerr << "********** MIDI Iterator = note on" << endl;
_event = MIDI::Event((*_note_iter)->on_event(), false);
_active_notes.push(*_note_iter);
++_note_iter;
} else if (type == NOTE_OFF) {
- //cerr << "********** MIDI Iterator = note off" << endl;
+ cerr << "********** MIDI Iterator = note off" << endl;
_event = MIDI::Event(_active_notes.top()->off_event(), false);
_active_notes.pop();
} else if (type == CC) {
- //cerr << "********** MIDI Iterator = CC" << endl;
+ cerr << "********** MIDI Iterator = CC" << endl;
_model->control_to_midi_event(_event, *_control_iter);
} else {
- //cerr << "********** MIDI Iterator = END" << endl;
+ cerr << "********** MIDI Iterator = END" << endl;
_is_end = true;
- _model->read_unlock();
- _locked = false;
}
assert(_is_end || _event.size() > 0);
@@ -226,6 +257,7 @@ MidiModel::const_iterator::operator=(const const_iterator& other)
_model = other._model;
_event = other._event;
+ _active_notes = other._active_notes;
_is_end = other._is_end;
_locked = other._locked;
_note_iter = other._note_iter;
@@ -234,9 +266,6 @@ MidiModel::const_iterator::operator=(const const_iterator& other)
assert( ! _event.owns_buffer());
- if (_locked)
- _model->read_lock();
-
return *this;
}
@@ -265,16 +294,16 @@ MidiModel::MidiModel(Session& s, size_t size)
size_t
MidiModel::read(MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframes_t stamp_offset) const
{
- //cerr << this << " MM::read @ " << start << " * " << nframes << " + " << stamp_offset << endl;
- //cerr << this << " MM # notes: " << n_notes() << endl;
+ cerr << this << " MM::read @ " << start << " * " << nframes << " + " << stamp_offset << endl;
+ cerr << this << " MM # notes: " << n_notes() << endl;
size_t read_events = 0;
if (start != _next_read) {
_read_iter = const_iterator(*this, (double)start);
- //cerr << "Repositioning iterator from " << _next_read << " to " << start << endl;
+ cerr << "Repositioning iterator from " << _next_read << " to " << start << endl;
} else {
- //cerr << "Using cached iterator at " << _next_read << endl;
+ cerr << "Using cached iterator at " << _next_read << endl;
}
_next_read = start + nframes;
@@ -282,7 +311,11 @@ MidiModel::read(MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframes
while (_read_iter != end() && _read_iter->time() < start + nframes) {
assert(_read_iter->size() > 0);
dst.write(_read_iter->time() + stamp_offset, _read_iter->size(), _read_iter->buffer());
- //cerr << this << " MM::read event @ " << _read_iter->time() << endl;
+ cerr << this << " MM::read event @ " << _read_iter->time()
+ << " type: " << hex << int(_read_iter->type()) << dec
+ << " note: " << int(_read_iter->note())
+ << " velocity: " << int(_read_iter->velocity())
+ << endl;
++_read_iter;
++read_events;
}