13
0

make per-region note-tracking in MidiPlaylist work correctly, or something very close to it. note that locking isssues remain when regions (and thus note trackers) are removed

git-svn-id: svn://localhost/ardour2/branches/3.0@5912 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2009-10-25 14:42:46 +00:00
parent e0a2d49869
commit de5e463904
6 changed files with 73 additions and 30 deletions

View File

@ -77,9 +77,10 @@ print_help (const char *execname)
static void
list_debug_options ()
{
cerr << _("The following debug options are available. Their use is case-insensitive.") << "\n\n";
cerr << _("The following debug options are available. Separate multipe options with commas. Names are case-insensitive.") << "\n\n";
cerr << "\tMidiSourceIO\n";
cerr << "\tMidiPlaylistIO\n";
cerr << "\tMidiDiskstreamIO\n";
}
static int
@ -99,12 +100,21 @@ parse_debug_options (const char* str)
return 1;
}
if (strcasecmp (p, "all") == 0) {
ARDOUR::set_debug_bits (~0ULL);
free (copy);
return 0;
}
if (strcasecmp (p, "midisourceio") == 0) {
bits |= ARDOUR::DEBUG::MidiSourceIO;
}
if (strcasecmp (p, "midiplaylistio") == 0) {
bits |= ARDOUR::DEBUG::MidiPlaylistIO;
}
if (strcasecmp (p, "mididiskstreamio") == 0) {
bits |= ARDOUR::DEBUG::MidiDiskstreamIO;
}
p = strtok_r (0, ",", &sp);
}

View File

@ -34,7 +34,8 @@ namespace ARDOUR {
enum DebugBits {
MidiSourceIO = 0x1,
MidiPlaylistIO = 0x2
MidiPlaylistIO = 0x2,
MidiDiskstreamIO = 0x4
};
}

View File

@ -59,6 +59,8 @@ public:
std::set<Evoral::Parameter> contained_automation();
void clear_note_trackers ();
protected:
/* playlist "callbacks" */

View File

@ -41,6 +41,7 @@
#include "ardour/butler.h"
#include "ardour/configuration.h"
#include "ardour/cycle_timer.h"
#include "ardour/debug.h"
#include "ardour/io.h"
#include "ardour/midi_diskstream.h"
#include "ardour/midi_playlist.h"
@ -1049,6 +1050,10 @@ MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool a
delete *ci;
}
if (_playlist) {
midi_playlist()->clear_note_trackers ();
}
capture_info.clear ();
capture_start_frame = 0;
}
@ -1473,14 +1478,13 @@ MidiDiskstream::get_playback (MidiBuffer& dst, nframes_t start, nframes_t end)
// Translates stamps to be relative to start
_playback_buf->read(dst, start, end);
#if 0
#ifndef NDEBUG
const size_t events_read = _playback_buf->read(dst, start, end);
cout << _name << ": MDS events read = " << events_read
<< " start = " << start << " end = " << end
<< " readspace " << _playback_buf->read_space()
<< " writespace " << _playback_buf->write_space() << endl;
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6\n", _name, events_read, start, end,
_playback_buf->read_space(), _playback_buf->write_space()));
#else
_playback_buf->read(dst, start, end);
#endif
gint32 frames_read = end - start;

View File

@ -124,10 +124,19 @@ MidiPlaylist::read (MidiRingBuffer<nframes_t>& dst, nframes_t start, nframes_t d
/* add it the set of trackers we will do note resolution
on, and remove it from the list we are keeping
around, because we don't need it anymore.
if the end of the region (where we want to theoretically resolve notes)
is outside the current read range, then just do it at the start
of this read range.
*/
tracker_info.push_back (TrackerInfo (t->second, (*i)->last_frame()));
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("time to resolve & remove tracker for %1\n", (*i)->name()));
nframes64_t resolve_at = (*i)->last_frame();
if (resolve_at >= end) {
resolve_at = start;
}
tracker_info.push_back (TrackerInfo (t->second, resolve_at));
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("time to resolve & remove tracker for %1 @ %2\n", (*i)->name(), resolve_at));
note_cnt += (t->second->on());
_note_trackers.erase (t);
}
@ -196,11 +205,12 @@ MidiPlaylist::read (MidiRingBuffer<nframes_t>& dst, nframes_t start, nframes_t d
delete (*t).first;
}
#ifndef NDEBUG
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("After resolution we now have %1 events\n", evlist.size()));
for (Evoral::EventList<nframes_t>::iterator x = evlist.begin(); x != evlist.end(); ++x) {
DEBUG_STR_SET(a,**x);
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\t%1\n", DEBUG_STR(a)));
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\t%1\n", **x));
}
#endif
RegionSortByLayer layer_cmp;
sort(regs.begin(), regs.end(), layer_cmp);
@ -233,12 +243,13 @@ MidiPlaylist::read (MidiRingBuffer<nframes_t>& dst, nframes_t start, nframes_t d
mr->read_at (evlist, start, dur, chan_n, _note_mode, tracker);
_read_data_count += mr->read_data_count();
#ifndef NDEBUG
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("After %1 (%2 .. %3) we now have %4\n", mr->name(), mr->position(), mr->last_frame(), evlist.size()));
for (Evoral::EventList<nframes_t>::iterator x = evlist.begin(); x != evlist.end(); ++x) {
DEBUG_STR_SET(a,**x);
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\t%1\n", DEBUG_STR(a)));
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\t%1\n", **x));
}
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\tAFTER: tracker says there are %1 on notes\n", tracker->on()));
#endif
if (new_tracker) {
pair<Region*,MidiStateTracker*> newpair;
@ -249,24 +260,25 @@ MidiPlaylist::read (MidiRingBuffer<nframes_t>& dst, nframes_t start, nframes_t d
}
}
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("Final we now have %1 events\n", evlist.size()));
for (Evoral::EventList<nframes_t>::iterator x = evlist.begin(); x != evlist.end(); ++x) {
DEBUG_STR_SET(a,**x);
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\t%1\n", DEBUG_STR(a)));
}
if (!evlist.empty()) {
/* sort the event list */
EventsSortByTime<nframes_t> time_cmp;
evlist.sort (time_cmp);
#ifndef NDEBUG
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("Final we now have %1 events\n", evlist.size()));
for (Evoral::EventList<nframes_t>::iterator x = evlist.begin(); x != evlist.end(); ++x) {
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\t%1\n", **x));
}
#endif
/* write into dst */
for (Evoral::EventList<nframes_t>::iterator e = evlist.begin(); e != evlist.end(); ++e) {
Evoral::Event<nframes_t>* ev (*e);
dst.write (ev->time(), ev->event_type(), ev->size(), ev->buffer());
delete ev;
}
}
}
@ -274,6 +286,16 @@ MidiPlaylist::read (MidiRingBuffer<nframes_t>& dst, nframes_t start, nframes_t d
return dur;
}
void
MidiPlaylist::clear_note_trackers ()
{
Glib::RecMutex::Lock rm (region_lock);
for (NoteTrackers::iterator n = _note_trackers.begin(); n != _note_trackers.end(); ++n) {
delete n->second;
}
_note_trackers.clear ();
}
void
MidiPlaylist::remove_dependents (boost::shared_ptr<Region> region)
{

View File

@ -16,13 +16,15 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "pbd/compose.h"
#include "ardour/debug.h"
#include "ardour/midi_ring_buffer.h"
#include "ardour/midi_buffer.h"
#include "ardour/event_type_map.h"
using namespace std;
namespace ARDOUR {
using namespace ARDOUR;
/** Read a block of MIDI events from buffer into a MidiBuffer.
*
@ -48,11 +50,13 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes
this->full_peek(sizeof(T), (uint8_t*)&ev_time);
if (ev_time > end) {
// cerr << "MRB event @ " << ev_time << " past end @ " << end << endl;
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MRB event @ %1 past end @ %2\n", ev_time, end));
break;
} else if (ev_time < start) {
// cerr << "MRB event @ " << ev_time << " before start @ " << start << endl;
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MRB event @ %1 before start @ %2\n", ev_time, start));
break;
} else {
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MRB event @ %1 in range %2 .. %3\n", ev_time, start, end));
}
bool success = read_prefix(&ev_time, &ev_type, &ev_size);
@ -100,12 +104,14 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes
// write MIDI buffer contents
success = Evoral::EventRingBuffer<T>::full_read(ev_size, write_loc);
#if 0
cerr << "wrote MidiEvent to Buffer: " << hex;
#ifndef NDEBUG
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, "wrote MidiEvent to Buffer: ");
for (size_t i=0; i < ev_size; ++i) {
cerr << (int) write_loc[i] << ' ';
DEBUG_STR_SET(a, hex);
DEBUG_STR(a) << "0x" << (int)write_loc[i] << ' ';
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, DEBUG_STR(a).str());
}
cerr << dec << endl;
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, "\n");
#endif
if (success) {
@ -201,5 +207,3 @@ MidiRingBuffer<T>::dump(ostream& str)
template class MidiRingBuffer<nframes_t>;
} // namespace ARDOUR