summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-09-16 01:08:51 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-09-16 01:08:51 +0000
commitfa4e858eb351668bc6687819903d019703daef7a (patch)
tree1068e35899ec48cdd8ef514510fec56092466673 /libs
parent127b8a62b790c7515a27934b920e88b7de04b7fc (diff)
do not allow smf_source's reads to stomp on cached read_end position in parent class, which creates chaos by being out of sync with MidiSource::_model_iterator. this doesn't totally fix MIDI playback, but it helps
git-svn-id: svn://localhost/ardour2/branches/3.0@5665 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/midi_ring_buffer.h1
-rw-r--r--libs/ardour/ardour/smf_source.h1
-rw-r--r--libs/ardour/midi_buffer.cc1
-rw-r--r--libs/ardour/midi_diskstream.cc7
-rw-r--r--libs/ardour/midi_playlist.cc2
-rw-r--r--libs/ardour/midi_region.cc13
-rw-r--r--libs/ardour/midi_ring_buffer.cc94
-rw-r--r--libs/ardour/midi_source.cc9
-rw-r--r--libs/ardour/smf_source.cc8
-rw-r--r--libs/evoral/evoral/Event.hpp6
-rw-r--r--libs/evoral/src/SMF.cpp8
-rw-r--r--libs/evoral/src/Sequence.cpp10
12 files changed, 121 insertions, 39 deletions
diff --git a/libs/ardour/ardour/midi_ring_buffer.h b/libs/ardour/ardour/midi_ring_buffer.h
index 228479067f..f879aa7534 100644
--- a/libs/ardour/ardour/midi_ring_buffer.h
+++ b/libs/ardour/ardour/midi_ring_buffer.h
@@ -51,6 +51,7 @@ public:
inline bool read_contents(uint32_t size, uint8_t* buf);
size_t read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes_t offset=0);
+ void dump(std::ostream& dst);
/** Set the channel filtering mode.
* @param mask If mode is FilterChannels, each bit represents a midi channel:
diff --git a/libs/ardour/ardour/smf_source.h b/libs/ardour/ardour/smf_source.h
index 73bef5480a..025f770fc3 100644
--- a/libs/ardour/ardour/smf_source.h
+++ b/libs/ardour/ardour/smf_source.h
@@ -85,6 +85,7 @@ private:
double _last_ev_time_beats;
sframes_t _last_ev_time_frames;
+ mutable sframes_t _smf_last_read_end;
};
}; /* namespace ARDOUR */
diff --git a/libs/ardour/midi_buffer.cc b/libs/ardour/midi_buffer.cc
index 12b46e7f04..ae3071a53c 100644
--- a/libs/ardour/midi_buffer.cc
+++ b/libs/ardour/midi_buffer.cc
@@ -93,7 +93,6 @@ MidiBuffer::read_from (const Buffer& src, nframes_t nframes, nframes_t dst_offse
const Evoral::MIDIEvent<TimeType> ev(*i, false);
if (ev.time() >= src_offset && ev.time() < (nframes+src_offset)) {
push_back (ev);
- cerr << "got note " << ev << endl;
}
}
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index 9c8c9e8620..6e57714ae2 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -858,8 +858,6 @@ MidiDiskstream::can_internal_playback_seek (nframes_t distance)
int
MidiDiskstream::internal_playback_seek (nframes_t distance)
{
- cerr << "MDS: internal_playback_seek " << distance << endl;
-
first_recordable_frame += distance;
playback_sample += distance;
@@ -929,8 +927,7 @@ MidiDiskstream::read (nframes_t& start, nframes_t dur, bool reversed)
_id, this_read, start) << endmsg;
return -1;
}
-
- //cout << "MDS this read " << this_read << " start = " << start << endl;
+
g_atomic_int_add(&_frames_written_to_ringbuffer, this_read);
_read_data_count = _playlist->read_data_count();
@@ -1650,7 +1647,9 @@ 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
const size_t events_read = _playback_buf->read(dst, start, end);
cout << _name << ": MDS events read = " << events_read
diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc
index 8f8b882d1e..82f8827f21 100644
--- a/libs/ardour/midi_playlist.cc
+++ b/libs/ardour/midi_playlist.cc
@@ -91,7 +91,7 @@ MidiPlaylist::MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, string
out_o++;
out_n++;
}
- // cerr << "HUH!? second region in the crossfade not found!" << endl;
+ // cerr << "HUH!? second region in the crossfade not found!" << endl;
}
}
diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc
index 910789c7fb..aca8d039ad 100644
--- a/libs/ardour/midi_region.cc
+++ b/libs/ardour/midi_region.cc
@@ -147,7 +147,7 @@ MidiRegion::_read_at (const SourceList& /*srcs*/, MidiRingBuffer<nframes_t>& dst
nframes_t internal_offset = 0;
nframes_t src_offset = 0;
nframes_t to_read = 0;
-
+
/* precondition: caller has verified that we cover the desired section */
assert(chan_n == 0);
@@ -191,7 +191,16 @@ MidiRegion::_read_at (const SourceList& /*srcs*/, MidiRingBuffer<nframes_t>& dst
// _start from the note times in the midi source
negative_output_buffer_position = _start;
}
-
+
+#if 0
+ cerr << "\t\tsource read from " << _position << " - " << _start << " (" << _position - _start << ") "
+ << " start in source " << _start << " + " << internal_offset << " (" << _start + internal_offset << ") "
+ << " dur = " << to_read
+ << " offset = " << output_buffer_position
+ << " negoffset = " << negative_output_buffer_position
+ << endl;
+#endif
+
if (src->midi_read (
dst, // destination buffer
_position - _start, // start position of the source in this read context
diff --git a/libs/ardour/midi_ring_buffer.cc b/libs/ardour/midi_ring_buffer.cc
index 88064c8798..5fcd3e8298 100644
--- a/libs/ardour/midi_ring_buffer.cc
+++ b/libs/ardour/midi_ring_buffer.cc
@@ -43,17 +43,15 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes
size_t count = 0;
- //cerr << "MRB read " << start << " .. " << end << " + " << offset << endl;
-
while (this->read_space() >= sizeof(T) + sizeof(Evoral::EventType) + sizeof(uint32_t)) {
this->full_peek(sizeof(T), (uint8_t*)&ev_time);
-
+
if (ev_time > end) {
- //cerr << "MRB event @ " << ev_time << " past end @ " << end << endl;
+ // cerr << "MRB event @ " << ev_time << " past end @ " << end << endl;
break;
} else if (ev_time < start) {
- //cerr << "MRB event @ " << ev_time << " before start @ " << start << endl;
+ // cerr << "MRB event @ " << ev_time << " before start @ " << start << endl;
break;
}
@@ -67,7 +65,7 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes
if (ev_type == LoopEventType) {
/*ev_time -= start;
ev_time += offset;*/
- cerr << "MRB loop boundary @ " << ev_time << endl;
+ // cerr << "MRB loop boundary @ " << ev_time << endl;
// Return without reading data or writing to buffer (loop events have no data)
// FIXME: This is not correct, loses events after the loop this cycle
@@ -87,11 +85,7 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes
continue;
}
}
-
- /*cerr << "MRB " << this << " - Reading event, time = "
- << ev_time << " - " << start << " => " << ev_time - start
- << ", size = " << ev_size << endl;*/
-
+
assert(ev_time >= start);
ev_time -= start;
ev_time += offset;
@@ -126,6 +120,84 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes
return count;
}
+template<typename T>
+void
+MidiRingBuffer<T>::dump(ostream& str)
+{
+ size_t rspace;
+
+ if ((rspace = this->read_space()) == 0) {
+ str << "MRB::dump: empty\n";
+ return;
+ }
+
+ T ev_time;
+ Evoral::EventType ev_type;
+ uint32_t ev_size;
+ size_t read_ptr = g_atomic_int_get (&this->_read_ptr);
+
+ str << "Dump @ " << read_ptr << endl;
+
+ while (1) {
+ uint8_t* wp;
+ uint8_t* data;
+ size_t write_ptr;
+
+#define space(r,w) ((w > r) ? (w - r) : ((w - r + this->_size) % this->_size))
+
+ write_ptr = g_atomic_int_get (&this->_write_ptr);
+ if (space (read_ptr, write_ptr) < sizeof (T)) {
+ break;
+ }
+
+ wp = &this->_buf[read_ptr];
+ memcpy (&ev_time, wp, sizeof (T));
+ read_ptr = (read_ptr + sizeof (T)) % this->_size;
+ str << "time " << ev_time;
+
+ write_ptr = g_atomic_int_get (&this->_write_ptr);
+ if (space (read_ptr, write_ptr) < sizeof (ev_type)) {
+ break;
+ }
+
+ wp = &this->_buf[read_ptr];
+ memcpy (&ev_type, wp, sizeof (ev_type));
+ read_ptr = (read_ptr + sizeof (ev_type)) % this->_size;
+ str << " type " << ev_type;
+
+ write_ptr = g_atomic_int_get (&this->_write_ptr);
+ if (space (read_ptr, write_ptr) < sizeof (ev_size)) {
+ str << "!OUT!\n";
+ break;
+ }
+
+ wp = &this->_buf[read_ptr];
+ memcpy (&ev_size, wp, sizeof (ev_size));
+ read_ptr = (read_ptr + sizeof (ev_size)) % this->_size;
+ str << " size " << ev_size;
+
+ write_ptr = g_atomic_int_get (&this->_write_ptr);
+ if (space (read_ptr, write_ptr) < ev_size) {
+ str << "!OUT!\n";
+ break;
+ }
+
+ data = new uint8_t[ev_size];
+
+ wp = &this->_buf[read_ptr];
+ memcpy (data, wp, ev_size);
+ read_ptr = (read_ptr + ev_size) % this->_size;
+
+ for (uint32_t i = 0; i != ev_size; ++i) {
+ str << ' ' << hex << (int) data[i] << dec;
+ }
+
+ str << endl;
+
+ delete [] data;
+ }
+}
+
template class MidiRingBuffer<nframes_t>;
diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc
index f16ebf186f..4da2dbb845 100644
--- a/libs/ardour/midi_source.cc
+++ b/libs/ardour/midi_source.cc
@@ -137,16 +137,15 @@ MidiSource::midi_read (MidiRingBuffer<nframes_t>& dst, sframes_t source_start,
#define BEATS_TO_FRAMES(t) (converter.to(t) + stamp_offset - negative_stamp_offset)
Evoral::Sequence<double>::const_iterator& i = _model_iter;
-
- if (_last_read_end == 0 || start != _last_read_end) { // || !i.valid()) {
- //cerr << "MidiSource seeking to " << start << " from " << _last_read_end << endl;
+
+ if (_last_read_end == 0 || start != _last_read_end || !i.valid()) {
for (i = _model->begin(); i != _model->end(); ++i) {
if (BEATS_TO_FRAMES(i->time()) >= start) {
break;
}
}
}
-
+
_last_read_end = start + cnt;
for (; i != _model->end(); ++i) {
@@ -234,7 +233,7 @@ MidiSource::session_saved()
stringstream ss(basename.substr(last_dash+1));
unsigned write_count = 0;
ss >> write_count;
- cerr << "WRITE COUNT: " << write_count << endl;
+ // cerr << "WRITE COUNT: " << write_count << endl;
++write_count; // start at 1
ss.clear();
ss << basename.substr(0, last_dash) << "-" << write_count;
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index 7db027124b..7fbc8b0287 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -55,6 +55,7 @@ SMFSource::SMFSource (Session& s, const ustring& path, bool embedded, Source::Fl
, Evoral::SMF()
, _last_ev_time_beats(0.0)
, _last_ev_time_frames(0)
+ , _smf_last_read_end (0)
{
if (init(_name, false)) {
throw failed_constructor ();
@@ -72,6 +73,7 @@ SMFSource::SMFSource (Session& s, const XMLNode& node, bool must_exist)
, FileSource(s, node, must_exist)
, _last_ev_time_beats(0.0)
, _last_ev_time_frames(0)
+ , _smf_last_read_end (0)
{
if (set_state(node)) {
throw failed_constructor ();
@@ -116,20 +118,20 @@ SMFSource::read_unlocked (MidiRingBuffer<nframes_t>& destination, sframes_t sour
const uint64_t start_ticks = (uint64_t)(converter.from(start) * ppqn());
- if (_last_read_end == 0 || start != _last_read_end) {
+ if (_smf_last_read_end == 0 || start != _smf_last_read_end) {
//cerr << "SMFSource::read_unlocked seeking to " << start << endl;
Evoral::SMF::seek_to_start();
while (time < start_ticks) {
ret = read_event(&ev_delta_t, &ev_size, &ev_buffer);
if (ret == -1) { // EOF
- _last_read_end = start + duration;
+ _smf_last_read_end = start + duration;
return duration;
}
time += ev_delta_t; // accumulate delta time
}
}
- _last_read_end = start + duration;
+ _smf_last_read_end = start + duration;
while (true) {
ret = read_event(&ev_delta_t, &ev_size, &ev_buffer);
diff --git a/libs/evoral/evoral/Event.hpp b/libs/evoral/evoral/Event.hpp
index 3e8e05fa3b..cc24ac87f7 100644
--- a/libs/evoral/evoral/Event.hpp
+++ b/libs/evoral/evoral/Event.hpp
@@ -199,12 +199,12 @@ protected:
template<typename Time>
std::ostream& operator<<(std::ostream& o, const Evoral::Event<Time>& ev) {
- o << "Event type = " << ev.event_type() << " @ " << " @ " << ev.time() << "\n\t";
+ o << "Event type = " << ev.event_type() << " @ " << ev.time();
o << std::hex;
for (uint32_t n = 0; n < ev.size(); ++n) {
- o << (int) ev.buffer()[n] << ' ';
+ o << ' ' << (int) ev.buffer()[n];
}
- o << std::dec << std::endl;
+ o << std::dec;
return o;
}
diff --git a/libs/evoral/src/SMF.cpp b/libs/evoral/src/SMF.cpp
index 2103ad8eae..424b4d46f2 100644
--- a/libs/evoral/src/SMF.cpp
+++ b/libs/evoral/src/SMF.cpp
@@ -205,10 +205,10 @@ SMF::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const
assert(midi_event_is_valid(*buf, *size));
- /*printf("SMF::read_event:\n");
+ /* printf("SMF::read_event @ %u: ", *delta_t);
for (size_t i = 0; i < *size; ++i) {
printf("%X ", (*buf)[i]);
- } printf("\n");*/
+ } printf("\n") */
return event_size;
} else {
@@ -223,10 +223,10 @@ SMF::append_event_delta(uint32_t delta_t, uint32_t size, const uint8_t* buf)
return;
}
- /*printf("SMF::append_event_delta:\n");
+ /* printf("SMF::append_event_delta @ %u:", delta_t);
for (size_t i = 0; i < size; ++i) {
printf("%X ", buf[i]);
- } printf("\n");*/
+ } printf("\n"); */
if (!midi_event_is_valid(buf, size)) {
cerr << "WARNING: SMF ignoring illegal MIDI event" << endl;
diff --git a/libs/evoral/src/Sequence.cpp b/libs/evoral/src/Sequence.cpp
index 3b1729cfe8..91943c03a6 100644
--- a/libs/evoral/src/Sequence.cpp
+++ b/libs/evoral/src/Sequence.cpp
@@ -33,7 +33,7 @@
#include "evoral/TypeMap.hpp"
#include "evoral/midi_util.h"
-//#define DEBUG_SEQUENCE 1
+// #define DEBUG_SEQUENCE 1
#ifdef DEBUG_SEQUENCE
#include <boost/format.hpp>
using boost::format;
@@ -209,10 +209,10 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t
_locked = false;
_seq->read_unlock();
} else {
- DUMP(format("New iterator = %1% : %2% @ %3%\n")
- % (int)_event->event_type()
- % (int)((MIDIEvent<Time>*)_event.get())->type()
- % _event->time());
+ DUMP(printf("New iterator = 0x%x : 0x%x @ %f\n",
+ (int)_event->event_type(),
+ (int)((MIDIEvent<Time>*)_event.get())->type(),
+ _event->time()));
assert(midi_event_is_valid(_event->buffer(), _event->size()));
}
}