From ed2beaffeef72ddce8ac628cced672851ec5668d Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 22 Dec 2011 20:14:47 +0000 Subject: main fix: when transport stops, clear per-region per-playlist note trackers even if there is no capture data to process; side effects: remove unused MidiBuffer::merge() and add DEBUG::MidiTrackers as well as more and better MIDI debug tracing facilities git-svn-id: svn://localhost/ardour2/branches/3.0@11057 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/debug.h | 1 + libs/ardour/ardour/midi_buffer.h | 1 - libs/ardour/buffer_set.cc | 8 +++-- libs/ardour/debug.cc | 1 + libs/ardour/midi_buffer.cc | 68 +++++++++++---------------------------- libs/ardour/midi_diskstream.cc | 10 +++--- libs/ardour/midi_playlist.cc | 1 + libs/ardour/midi_region.cc | 2 +- libs/ardour/midi_source.cc | 5 +-- libs/ardour/midi_state_tracker.cc | 23 +++++++++++++ libs/ardour/midi_track.cc | 1 + 11 files changed, 61 insertions(+), 60 deletions(-) (limited to 'libs') diff --git a/libs/ardour/ardour/debug.h b/libs/ardour/ardour/debug.h index 8ab4a4d9fd..58bc4f7af4 100644 --- a/libs/ardour/ardour/debug.h +++ b/libs/ardour/ardour/debug.h @@ -55,6 +55,7 @@ namespace PBD { extern uint64_t AudioUnits; extern uint64_t ControlProtocols; extern uint64_t CycleTimers; + extern uint64_t MidiTrackers; } } diff --git a/libs/ardour/ardour/midi_buffer.h b/libs/ardour/ardour/midi_buffer.h index 611e890304..db02344249 100644 --- a/libs/ardour/ardour/midi_buffer.h +++ b/libs/ardour/ardour/midi_buffer.h @@ -50,7 +50,6 @@ public: void resize(size_t); - bool merge(const MidiBuffer& a, const MidiBuffer& b); bool merge_in_place(const MidiBuffer &other); template diff --git a/libs/ardour/buffer_set.cc b/libs/ardour/buffer_set.cc index 2bd360b42c..caf6d7e8d2 100644 --- a/libs/ardour/buffer_set.cc +++ b/libs/ardour/buffer_set.cc @@ -23,6 +23,7 @@ #include #include +#include #include "pbd/compose.h" @@ -258,13 +259,16 @@ BufferSet::get_lv2_midi(bool input, size_t i) ebuf->reset(); if (input) { + DEBUG_TRACE (PBD::DEBUG::LV2, string_compose ("%1 bytes of MIDI waiting @ %2\n", mbuf.size(), (void*) mbuf.data())); for (MidiBuffer::iterator e = mbuf.begin(); e != mbuf.end(); ++e) { const Evoral::MIDIEvent ev(*e, false); uint32_t type = LV2Plugin::midi_event_type(); #ifndef NDEBUG - DEBUG_TRACE (PBD::DEBUG::LV2, string_compose ("(FLUSH) MIDI event of size %1\n", ev.size())); + DEBUG_TRACE (PBD::DEBUG::LV2, string_compose ("\tMIDI event of size %1 @ %2\n", ev.size(), ev.time())); for (uint16_t x = 0; x < ev.size(); ++x) { - DEBUG_TRACE (PBD::DEBUG::LV2, string_compose ("\tByte[%1] = %2\n", x, (int) ev.buffer()[x])); + std::stringstream ss; + ss << "\t\tByte[" << x << "] = " << std::hex << (int) ev.buffer()[x] << std::dec << std::endl; + DEBUG_TRACE (PBD::DEBUG::LV2, ss.str()); } #endif ebuf->append(ev.time(), 0, type, ev.size(), ev.buffer()); diff --git a/libs/ardour/debug.cc b/libs/ardour/debug.cc index de29a99b05..c18834219e 100644 --- a/libs/ardour/debug.cc +++ b/libs/ardour/debug.cc @@ -52,4 +52,5 @@ uint64_t PBD::DEBUG::PluginManager = PBD::new_debug_bit ("pluginmanager"); uint64_t PBD::DEBUG::AudioUnits = PBD::new_debug_bit ("audiounits"); uint64_t PBD::DEBUG::ControlProtocols = PBD::new_debug_bit ("controlprotocols"); uint64_t PBD::DEBUG::CycleTimers = PBD::new_debug_bit ("cycletimers"); +uint64_t PBD::DEBUG::MidiTrackers = PBD::new_debug_bit ("miditrackers"); diff --git a/libs/ardour/midi_buffer.cc b/libs/ardour/midi_buffer.cc index 8d07c308ee..efb7bba317 100644 --- a/libs/ardour/midi_buffer.cc +++ b/libs/ardour/midi_buffer.cc @@ -130,8 +130,6 @@ bool MidiBuffer::push_back(const Evoral::MIDIEvent& ev) { const size_t stamp_size = sizeof(TimeType); - /*cerr << "MidiBuffer: pushing event @ " << ev.time() - << " size = " << ev.size() << endl;*/ if (_size + stamp_size + ev.size() >= _capacity) { cerr << "MidiBuffer::push_back failed (buffer is full)" << endl; @@ -204,6 +202,7 @@ bool MidiBuffer::push_back(const jack_midi_event_t& ev) { const size_t stamp_size = sizeof(TimeType); + if (_size + stamp_size + ev.size >= _capacity) { cerr << "MidiBuffer::push_back failed (buffer is full)" << endl; return false; @@ -214,6 +213,21 @@ MidiBuffer::push_back(const jack_midi_event_t& ev) return false; } +#ifndef NDEBUG + if (DEBUG::MidiIO & PBD::debug_bits) { + DEBUG_STR_DECL(a); + DEBUG_STR_APPEND(a, string_compose ("midibuffer %1 push jack event @ %2 sz %3 ", this, ev.time, ev.size)); + for (size_t i=0; i < ev.size; ++i) { + DEBUG_STR_APPEND(a,hex); + DEBUG_STR_APPEND(a,"0x"); + DEBUG_STR_APPEND(a,(int)ev.buffer[i]); + DEBUG_STR_APPEND(a,' '); + } + DEBUG_STR_APPEND(a,'\n'); + DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str()); + } +#endif + uint8_t* const write_loc = _data + _size; *((TimeType*)write_loc) = ev.time; memcpy(write_loc + stamp_size, ev.buffer, ev.size); @@ -387,9 +401,9 @@ MidiBuffer::second_simultaneous_midi_byte_is_first (uint8_t a, uint8_t b) /** Merge \a other into this buffer. Realtime safe. */ bool -MidiBuffer::merge_in_place(const MidiBuffer &other) +MidiBuffer::merge_in_place (const MidiBuffer &other) { - if (other.size() || size()) { + if (other.size() && size()) { DEBUG_TRACE (DEBUG::MidiIO, string_compose ("merge in place, sizes %1/%2\n", size(), other.size())); } @@ -549,49 +563,3 @@ MidiBuffer::merge_in_place(const MidiBuffer &other) return true; } -/** Clear, and merge \a a and \a b into this buffer. - * - * \return true if complete merge was successful - */ -bool -MidiBuffer::merge(const MidiBuffer& a, const MidiBuffer& b) -{ - _size = 0; - - if (this == &a) { - return merge_in_place(b); - } else if (this == &b) { - return merge_in_place(a); - } - - const_iterator ai = a.begin(); - const_iterator bi = b.begin(); - - resize(a.size() + b.size()); - while (ai != a.end() && bi != b.end()) { - if ((*ai).time() < (*bi).time()) { - memcpy(_data + _size, (*ai).buffer(), (*ai).size()); - _size += (*ai).size(); - ++ai; - } else { - memcpy(_data + _size, (*bi).buffer(), (*bi).size()); - _size += (*bi).size(); - ++bi; - } - } - - while (ai != a.end()) { - memcpy(_data + _size, (*ai).buffer(), (*ai).size()); - _size += (*ai).size(); - ++ai; - } - - while (bi != b.end()) { - memcpy(_data + _size, (*bi).buffer(), (*bi).size()); - _size += (*bi).size(); - ++bi; - } - - return true; -} - diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index 64fcf60925..950e2b5e61 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -944,7 +944,7 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen Glib::Mutex::Lock lm (capture_info_lock); if (capture_info.empty()) { - return; + goto no_capture_stuff_to_do; } if (abort_capture) { @@ -1097,12 +1097,14 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen delete *ci; } + capture_info.clear (); + capture_start_frame = 0; + + no_capture_stuff_to_do: + if (_playlist) { midi_playlist()->clear_note_trackers (); } - - capture_info.clear (); - capture_start_frame = 0; } void diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc index 3486c38754..edadc225b0 100644 --- a/libs/ardour/midi_playlist.cc +++ b/libs/ardour/midi_playlist.cc @@ -281,6 +281,7 @@ MidiPlaylist::clear_note_trackers () for (NoteTrackers::iterator n = _note_trackers.begin(); n != _note_trackers.end(); ++n) { delete n->second; } + DEBUG_TRACE (DEBUG::MidiTrackers, string_compose ("%1 clears all note trackers\n", name())); _note_trackers.clear (); } diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index 5ace3f1fd1..fe98261248 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -258,7 +258,7 @@ MidiRegion::_read_at (const SourceList& /*srcs*/, Evoral::EventSink& src->set_note_mode(mode); /* - cerr << "MR read @ " << position << " * " << to_read + cerr << "MR " << name () << " read @ " << position << " * " << to_read << " _position = " << _position << " _start = " << _start << " intoffset = " << internal_offset diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc index bddb392221..ad07269b6c 100644 --- a/libs/ardour/midi_source.cc +++ b/libs/ardour/midi_source.cc @@ -199,8 +199,8 @@ MidiSource::midi_read (Evoral::EventSink& dst, framepos_t source_sta BeatsFramesConverter converter(_session.tempo_map(), source_start); - DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("MidiSource::midi-read() sstart %1 start %2 cnt %3 tracker %4\n", - source_start, start, cnt, tracker)); + DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("MidiSource::midi-read() %5 sstart %1 start %2 cnt %3 tracker %4\n", + source_start, start, cnt, tracker, name())); if (_model) { Evoral::Sequence::const_iterator& i = _model_iter; @@ -210,6 +210,7 @@ MidiSource::midi_read (Evoral::EventSink& dst, framepos_t source_sta DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("*** %1 search for relevant iterator for %1 / %2\n", _name, source_start, start)); for (i = _model->begin(0, false, filtered); i != _model->end(); ++i) { if (converter.to(i->time()) >= start) { + DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("***\tstop iterator search @ %1\n", i->time())); break; } } diff --git a/libs/ardour/midi_state_tracker.cc b/libs/ardour/midi_state_tracker.cc index 342d9d0e58..a8f803a8a0 100644 --- a/libs/ardour/midi_state_tracker.cc +++ b/libs/ardour/midi_state_tracker.cc @@ -18,6 +18,10 @@ */ #include + +#include "pbd/compose.h" + +#include "ardour/debug.h" #include "ardour/event_type_map.h" #include "ardour/midi_ring_buffer.h" #include "ardour/midi_source.h" @@ -35,6 +39,7 @@ MidiStateTracker::MidiStateTracker () void MidiStateTracker::reset () { + DEBUG_TRACE (PBD::DEBUG::MidiTrackers, string_compose ("%1: reset\n", this)); memset (_active_notes, 0, sizeof (_active_notes)); _on = 0; } @@ -54,6 +59,8 @@ MidiStateTracker::add (uint8_t note, uint8_t chn) { ++_active_notes[note + 128 * chn]; ++_on; + DEBUG_TRACE (PBD::DEBUG::MidiTrackers, string_compose ("MST @ %1 ON %2/%3 total on %4\n", + this, (int) note, (int) chn, _on)); } void @@ -71,6 +78,8 @@ MidiStateTracker::remove (uint8_t note, uint8_t chn) break; } + DEBUG_TRACE (PBD::DEBUG::MidiTrackers, string_compose ("MST @ %1 OFF %2/%3 total on %4\n", + this, (int) note, (int) chn, _on)); } void @@ -78,6 +87,8 @@ MidiStateTracker::track (const MidiBuffer::iterator &from, const MidiBuffer::ite { looped = false; + DEBUG_TRACE (PBD::DEBUG::MidiTrackers, string_compose ("%1 track notes, looped = %2\n", this, looped)); + for (MidiBuffer::iterator i = from; i != to; ++i) { const Evoral::MIDIEvent ev(*i, false); if (ev.event_type() == LoopEventType) { @@ -100,6 +111,8 @@ MidiStateTracker::track (const MidiBuffer::iterator &from, const MidiBuffer::ite void MidiStateTracker::resolve_notes (MidiBuffer &dst, framepos_t time) { + DEBUG_TRACE (PBD::DEBUG::MidiTrackers, string_compose ("%1 MB-resolve notes @ %2 on = %3\n", this, time, _on)); + if (!_on) { return; } @@ -112,6 +125,8 @@ MidiStateTracker::resolve_notes (MidiBuffer &dst, framepos_t time) (MIDI_CMD_NOTE_OFF, time, 3, buffer, false); dst.push_back (noteoff); _active_notes[note + 128 * channel]--; + DEBUG_TRACE (PBD::DEBUG::MidiTrackers, string_compose ("%1: MB-resolved note %2/%3 at %4\n", + this, (int) note, (int) channel, time)); } } } @@ -123,6 +138,8 @@ MidiStateTracker::resolve_notes (Evoral::EventSink &dst, framepos_t { uint8_t buf[3]; + DEBUG_TRACE (PBD::DEBUG::MidiTrackers, string_compose ("%1 EVS-resolve notes @ %2 on = %3\n", this, time, _on)); + if (!_on) { return; } @@ -135,6 +152,8 @@ MidiStateTracker::resolve_notes (Evoral::EventSink &dst, framepos_t buf[2] = 0; dst.write (time, EventTypeMap::instance().midi_event_type (buf[0]), 3, buf); _active_notes[note + 128 * channel]--; + DEBUG_TRACE (PBD::DEBUG::MidiTrackers, string_compose ("%1: EVS-resolved note %2/%3 at %4\n", + this, (int) note, (int) channel, time)); } } } @@ -144,6 +163,8 @@ MidiStateTracker::resolve_notes (Evoral::EventSink &dst, framepos_t void MidiStateTracker::resolve_notes (MidiSource& src, Evoral::MusicalTime time) { + DEBUG_TRACE (PBD::DEBUG::MidiTrackers, string_compose ("%1 MS-resolve notes @ %2 on = %3\n", this, time, _on)); + if (!_on) { return; } @@ -159,6 +180,8 @@ MidiStateTracker::resolve_notes (MidiSource& src, Evoral::MusicalTime time) ev.set_note (note); ev.set_velocity (0); src.append_event_unlocked_beats (ev); + DEBUG_TRACE (PBD::DEBUG::MidiTrackers, string_compose ("%1: MS-resolved note %2/%3 at %4\n", + this, (int) note, (int) channel, time)); _active_notes[note + 128 * channel]--; /* don't stack events up at the same time */ time += 1.0/128.0; diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index e835008e67..4b990b8175 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -404,6 +404,7 @@ void MidiTrack::realtime_handle_transport_stopped () { Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK); + if (!lm.locked ()) { return; } -- cgit v1.2.3