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
This commit is contained in:
Paul Davis 2011-12-22 20:14:47 +00:00
parent 2449a787c5
commit ed2beaffee
11 changed files with 61 additions and 60 deletions

View File

@ -55,6 +55,7 @@ namespace PBD {
extern uint64_t AudioUnits;
extern uint64_t ControlProtocols;
extern uint64_t CycleTimers;
extern uint64_t MidiTrackers;
}
}

View 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>

View 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());

View 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");

View 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;
}

View 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

View 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 ();
}

View 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

View 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;
}
}

View File

@ -18,6 +18,10 @@
*/
#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;

View File

@ -404,6 +404,7 @@ void
MidiTrack::realtime_handle_transport_stopped ()
{
Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
if (!lm.locked ()) {
return;
}