main fix: when transport stops, clear per-region per-playlist note trackers even...
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 22 Dec 2011 20:14:47 +0000 (20:14 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 22 Dec 2011 20:14:47 +0000 (20:14 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@11057 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/debug.h
libs/ardour/ardour/midi_buffer.h
libs/ardour/buffer_set.cc
libs/ardour/debug.cc
libs/ardour/midi_buffer.cc
libs/ardour/midi_diskstream.cc
libs/ardour/midi_playlist.cc
libs/ardour/midi_region.cc
libs/ardour/midi_source.cc
libs/ardour/midi_state_tracker.cc
libs/ardour/midi_track.cc

index 8ab4a4d9fdfe9622f839454c5a52ea0013c9c2e8..58bc4f7af474573826006df1b99c81ae8beb4cd7 100644 (file)
@@ -55,6 +55,7 @@ namespace PBD {
                extern uint64_t AudioUnits;
                extern uint64_t ControlProtocols;
                extern uint64_t CycleTimers;
+               extern uint64_t MidiTrackers;
        }
 }
 
index 611e890304c1d8a0147e67d58c24af588bb49e22..db02344249ff8c8f7319fb08fbaca235ee51e243 100644 (file)
@@ -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<typename BufferType, typename EventType>
index 2bd360b42cf02afbb8f1ccf3c2e933fe919d412b..caf6d7e8d2e8fcd8b8570bae203f24b54e5b94a8 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <iostream>
 #include <algorithm>
+#include <sstream>
 
 #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<framepos_t> 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());
index de29a99b05f0608661a3c18fa0b7b244fa606e3b..c18834219e674c5c2d3c4edef96abb1d6526c7e2 100644 (file)
@@ -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");
 
index 8d07c308ee7428207a13d207731be0c5cec24714..efb7bba317f1f174c0400a85e6a62cdfc7732156 100644 (file)
@@ -130,8 +130,6 @@ bool
 MidiBuffer::push_back(const Evoral::MIDIEvent<TimeType>& 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;
-}
-
index 64fcf609258224ad25e3573afc7649c0af0c22ca..950e2b5e612bbc6d44019ee775a634a0c6ba34da 100644 (file)
@@ -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
index 3486c387543a2470c929c30f2b5f094a166ce48e..edadc225b0ba13ef89704834e1ecb0622a9fddf1 100644 (file)
@@ -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 ();
 }
 
index 5ace3f1fd18eff23e842ef8ee79302479a931545..fe98261248447be7f07f7da3b3c4f63c3dbce140 100644 (file)
@@ -258,7 +258,7 @@ MidiRegion::_read_at (const SourceList& /*srcs*/, Evoral::EventSink<framepos_t>&
        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
index bddb392221fbdffcbe8d9adcbf378e235fa4aa08..ad07269b6cec667405966e381d5bd904dfc815c4 100644 (file)
@@ -199,8 +199,8 @@ MidiSource::midi_read (Evoral::EventSink<framepos_t>& 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<double>::const_iterator& i = _model_iter;
@@ -210,6 +210,7 @@ MidiSource::midi_read (Evoral::EventSink<framepos_t>& 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;
                                }
                        }
index 342d9d0e58cca336ee448bed1d9ee916272f6f8e..a8f803a8a07abc9df4a4979eedffe8b1fed43c5d 100644 (file)
 */
 
 #include <iostream>
+
+#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<MidiBuffer::TimeType> 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<framepos_t> &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<framepos_t> &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<framepos_t> &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;
index e835008e67689800ddc1396f5e192ad3117dc38a..4b990b8175ef3ad1c1e40b709a0f4410c262a9b5 100644 (file)
@@ -404,6 +404,7 @@ void
 MidiTrack::realtime_handle_transport_stopped ()
 {
        Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
+
        if (!lm.locked ()) {
                return;
        }