mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 00:04:56 +01:00
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:
parent
e0a2d49869
commit
de5e463904
6 changed files with 73 additions and 30 deletions
|
|
@ -77,9 +77,10 @@ print_help (const char *execname)
|
||||||
static void
|
static void
|
||||||
list_debug_options ()
|
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 << "\tMidiSourceIO\n";
|
||||||
cerr << "\tMidiPlaylistIO\n";
|
cerr << "\tMidiPlaylistIO\n";
|
||||||
|
cerr << "\tMidiDiskstreamIO\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -99,12 +100,21 @@ parse_debug_options (const char* str)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcasecmp (p, "all") == 0) {
|
||||||
|
ARDOUR::set_debug_bits (~0ULL);
|
||||||
|
free (copy);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (strcasecmp (p, "midisourceio") == 0) {
|
if (strcasecmp (p, "midisourceio") == 0) {
|
||||||
bits |= ARDOUR::DEBUG::MidiSourceIO;
|
bits |= ARDOUR::DEBUG::MidiSourceIO;
|
||||||
}
|
}
|
||||||
if (strcasecmp (p, "midiplaylistio") == 0) {
|
if (strcasecmp (p, "midiplaylistio") == 0) {
|
||||||
bits |= ARDOUR::DEBUG::MidiPlaylistIO;
|
bits |= ARDOUR::DEBUG::MidiPlaylistIO;
|
||||||
}
|
}
|
||||||
|
if (strcasecmp (p, "mididiskstreamio") == 0) {
|
||||||
|
bits |= ARDOUR::DEBUG::MidiDiskstreamIO;
|
||||||
|
}
|
||||||
|
|
||||||
p = strtok_r (0, ",", &sp);
|
p = strtok_r (0, ",", &sp);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@ namespace ARDOUR {
|
||||||
|
|
||||||
enum DebugBits {
|
enum DebugBits {
|
||||||
MidiSourceIO = 0x1,
|
MidiSourceIO = 0x1,
|
||||||
MidiPlaylistIO = 0x2
|
MidiPlaylistIO = 0x2,
|
||||||
|
MidiDiskstreamIO = 0x4
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,8 @@ public:
|
||||||
|
|
||||||
std::set<Evoral::Parameter> contained_automation();
|
std::set<Evoral::Parameter> contained_automation();
|
||||||
|
|
||||||
|
void clear_note_trackers ();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/* playlist "callbacks" */
|
/* playlist "callbacks" */
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
#include "ardour/butler.h"
|
#include "ardour/butler.h"
|
||||||
#include "ardour/configuration.h"
|
#include "ardour/configuration.h"
|
||||||
#include "ardour/cycle_timer.h"
|
#include "ardour/cycle_timer.h"
|
||||||
|
#include "ardour/debug.h"
|
||||||
#include "ardour/io.h"
|
#include "ardour/io.h"
|
||||||
#include "ardour/midi_diskstream.h"
|
#include "ardour/midi_diskstream.h"
|
||||||
#include "ardour/midi_playlist.h"
|
#include "ardour/midi_playlist.h"
|
||||||
|
|
@ -1049,6 +1050,10 @@ MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool a
|
||||||
delete *ci;
|
delete *ci;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_playlist) {
|
||||||
|
midi_playlist()->clear_note_trackers ();
|
||||||
|
}
|
||||||
|
|
||||||
capture_info.clear ();
|
capture_info.clear ();
|
||||||
capture_start_frame = 0;
|
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
|
// 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);
|
const size_t events_read = _playback_buf->read(dst, start, end);
|
||||||
cout << _name << ": MDS events read = " << events_read
|
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6\n", _name, events_read, start, end,
|
||||||
<< " start = " << start << " end = " << end
|
_playback_buf->read_space(), _playback_buf->write_space()));
|
||||||
<< " readspace " << _playback_buf->read_space()
|
#else
|
||||||
<< " writespace " << _playback_buf->write_space() << endl;
|
_playback_buf->read(dst, start, end);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gint32 frames_read = end - start;
|
gint32 frames_read = end - start;
|
||||||
|
|
|
||||||
|
|
@ -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
|
/* add it the set of trackers we will do note resolution
|
||||||
on, and remove it from the list we are keeping
|
on, and remove it from the list we are keeping
|
||||||
around, because we don't need it anymore.
|
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()));
|
nframes64_t resolve_at = (*i)->last_frame();
|
||||||
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("time to resolve & remove tracker for %1\n", (*i)->name()));
|
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_cnt += (t->second->on());
|
||||||
_note_trackers.erase (t);
|
_note_trackers.erase (t);
|
||||||
}
|
}
|
||||||
|
|
@ -196,11 +205,12 @@ MidiPlaylist::read (MidiRingBuffer<nframes_t>& dst, nframes_t start, nframes_t d
|
||||||
delete (*t).first;
|
delete (*t).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("After resolution we now have %1 events\n", evlist.size()));
|
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) {
|
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", **x));
|
||||||
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\t%1\n", DEBUG_STR(a)));
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
RegionSortByLayer layer_cmp;
|
RegionSortByLayer layer_cmp;
|
||||||
sort(regs.begin(), regs.end(), 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);
|
mr->read_at (evlist, start, dur, chan_n, _note_mode, tracker);
|
||||||
_read_data_count += mr->read_data_count();
|
_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()));
|
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) {
|
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", **x));
|
||||||
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\t%1\n", DEBUG_STR(a)));
|
|
||||||
}
|
}
|
||||||
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\tAFTER: tracker says there are %1 on notes\n", tracker->on()));
|
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\tAFTER: tracker says there are %1 on notes\n", tracker->on()));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (new_tracker) {
|
if (new_tracker) {
|
||||||
pair<Region*,MidiStateTracker*> newpair;
|
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()) {
|
if (!evlist.empty()) {
|
||||||
|
|
||||||
/* sort the event list */
|
/* sort the event list */
|
||||||
EventsSortByTime<nframes_t> time_cmp;
|
EventsSortByTime<nframes_t> time_cmp;
|
||||||
evlist.sort (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 */
|
/* write into dst */
|
||||||
for (Evoral::EventList<nframes_t>::iterator e = evlist.begin(); e != evlist.end(); ++e) {
|
for (Evoral::EventList<nframes_t>::iterator e = evlist.begin(); e != evlist.end(); ++e) {
|
||||||
Evoral::Event<nframes_t>* ev (*e);
|
Evoral::Event<nframes_t>* ev (*e);
|
||||||
dst.write (ev->time(), ev->event_type(), ev->size(), ev->buffer());
|
dst.write (ev->time(), ev->event_type(), ev->size(), ev->buffer());
|
||||||
delete ev;
|
delete ev;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -274,6 +286,16 @@ MidiPlaylist::read (MidiRingBuffer<nframes_t>& dst, nframes_t start, nframes_t d
|
||||||
return dur;
|
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
|
void
|
||||||
MidiPlaylist::remove_dependents (boost::shared_ptr<Region> region)
|
MidiPlaylist::remove_dependents (boost::shared_ptr<Region> region)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,15 @@
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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_ring_buffer.h"
|
||||||
#include "ardour/midi_buffer.h"
|
#include "ardour/midi_buffer.h"
|
||||||
#include "ardour/event_type_map.h"
|
#include "ardour/event_type_map.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace ARDOUR;
|
||||||
namespace ARDOUR {
|
|
||||||
|
|
||||||
/** Read a block of MIDI events from buffer into a MidiBuffer.
|
/** 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);
|
this->full_peek(sizeof(T), (uint8_t*)&ev_time);
|
||||||
|
|
||||||
if (ev_time > end) {
|
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;
|
break;
|
||||||
} else if (ev_time < start) {
|
} 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;
|
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);
|
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
|
// write MIDI buffer contents
|
||||||
success = Evoral::EventRingBuffer<T>::full_read(ev_size, write_loc);
|
success = Evoral::EventRingBuffer<T>::full_read(ev_size, write_loc);
|
||||||
|
|
||||||
#if 0
|
#ifndef NDEBUG
|
||||||
cerr << "wrote MidiEvent to Buffer: " << hex;
|
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, "wrote MidiEvent to Buffer: ");
|
||||||
for (size_t i=0; i < ev_size; ++i) {
|
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
|
#endif
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
|
@ -201,5 +207,3 @@ MidiRingBuffer<T>::dump(ostream& str)
|
||||||
|
|
||||||
template class MidiRingBuffer<nframes_t>;
|
template class MidiRingBuffer<nframes_t>;
|
||||||
|
|
||||||
} // namespace ARDOUR
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue