Fix immediate event delivery (panic button, controller sliders, etc).
git-svn-id: svn://localhost/ardour2/branches/3.0@4353 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
@@ -96,7 +96,7 @@ MidiBuffer::copy(const MidiBuffer& copy)
|
||||
|
||||
|
||||
/** Read events from @a src starting at time @a offset into the START of this buffer, for
|
||||
* time direction @a nframes. Relative time, where 0 = start of buffer.
|
||||
* time duration @a nframes. Relative time, where 0 = start of buffer.
|
||||
*
|
||||
* Note that offset and nframes refer to sample time, NOT buffer offsets or event counts.
|
||||
*/
|
||||
@@ -118,13 +118,16 @@ MidiBuffer::read_from(const Buffer& src, nframes_t nframes, nframes_t offset)
|
||||
// FIXME: slow
|
||||
for (size_t i=0; i < msrc.size(); ++i) {
|
||||
const Evoral::MIDIEvent& ev = msrc[i];
|
||||
if (ev.time() < offset)
|
||||
continue;
|
||||
if (ev.time() < (nframes + offset)) {
|
||||
//cout << "MidiBuffer::read_from got event, " << int(ev.type()) << " time: " << ev.time() << " buffer size: " << _size << endl;
|
||||
//cout << "MidiBuffer::read_from event type: " << int(ev.type())
|
||||
// << " time: " << ev.time() << " buffer size: " << _size << endl;
|
||||
if (ev.time() < offset) {
|
||||
//cout << "MidiBuffer::read_from skipped event before " << offset << endl;
|
||||
} else if (ev.time() < (nframes + offset)) {
|
||||
//cout << "MidiBuffer::read_from appending event" << endl;
|
||||
push_back(ev);
|
||||
} else {
|
||||
cerr << "MidiBuffer event out of range, " << ev.time() << endl;
|
||||
//cerr << "MidiBuffer::read_from skipped event after "
|
||||
// << nframes << " + " << offset << endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,18 +145,25 @@ MidiBuffer::read_from(const Buffer& src, nframes_t nframes, nframes_t offset)
|
||||
bool
|
||||
MidiBuffer::push_back(const Evoral::MIDIEvent& ev)
|
||||
{
|
||||
if (_size == _capacity)
|
||||
if (_size == _capacity) {
|
||||
cerr << "MidiBuffer::push_back failed (buffer is full)" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t* const write_loc = _data + (_size * MAX_EVENT_SIZE);
|
||||
|
||||
memcpy(write_loc, ev.buffer(), ev.size());
|
||||
_events[_size] = ev;
|
||||
_events[_size].set_buffer(ev.size(), write_loc, false);
|
||||
|
||||
/*cerr << "MidiBuffer: pushed @ " << _events[_size].time()
|
||||
<< " size = " << _size << endl;
|
||||
for (size_t i = 0; i < _events[_size].size(); ++i) {
|
||||
printf("%X ", _events[_size].buffer()[i]);
|
||||
}
|
||||
printf("\n");*/
|
||||
|
||||
++_size;
|
||||
|
||||
//cerr << "MidiBuffer: pushed, size = " << _size << endl;
|
||||
|
||||
_silent = false;
|
||||
|
||||
return true;
|
||||
@@ -170,18 +180,25 @@ MidiBuffer::push_back(const Evoral::MIDIEvent& ev)
|
||||
bool
|
||||
MidiBuffer::push_back(const jack_midi_event_t& ev)
|
||||
{
|
||||
if (_size == _capacity)
|
||||
if (_size == _capacity) {
|
||||
cerr << "MidiBuffer::push_back failed (buffer is full)" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t* const write_loc = _data + (_size * MAX_EVENT_SIZE);
|
||||
|
||||
memcpy(write_loc, ev.buffer, ev.size);
|
||||
_events[_size].time() = (double)ev.time;
|
||||
_events[_size].set_buffer(ev.size, write_loc, false);
|
||||
|
||||
/*cerr << "MidiBuffer: pushed @ " << _events[_size].time()
|
||||
<< " size = " << _size << endl;
|
||||
for (size_t i = 0; i < _events[_size].size(); ++i) {
|
||||
printf("%X ", _events[_size].buffer()[i]);
|
||||
}
|
||||
printf("\n");*/
|
||||
|
||||
++_size;
|
||||
|
||||
//cerr << "MidiBuffer: pushed, size = " << _size << endl;
|
||||
|
||||
_silent = false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "ardour/midi_buffer.h"
|
||||
#include "ardour/event_type_map.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
/** Read a block of MIDI events from buffer.
|
||||
@@ -31,7 +33,7 @@ size_t
|
||||
MidiRingBuffer::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes_t offset)
|
||||
{
|
||||
if (read_space() == 0) {
|
||||
//std::cerr << "MRB: NO READ SPACE" << std::endl;
|
||||
//cerr << "MRB: NO READ SPACE" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -41,23 +43,23 @@ MidiRingBuffer::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes_t
|
||||
|
||||
size_t count = 0;
|
||||
|
||||
//std::cerr << "MRB read " << start << " .. " << end << " + " << offset << std::endl;
|
||||
//cerr << "MRB read " << start << " .. " << end << " + " << offset << endl;
|
||||
|
||||
while (read_space() >= sizeof(Evoral::EventTime) + sizeof(Evoral::EventType) + sizeof(uint32_t)) {
|
||||
|
||||
full_peek(sizeof(Evoral::EventTime), (uint8_t*)&ev_time);
|
||||
|
||||
if (ev_time > end) {
|
||||
//std::cerr << "MRB: PAST END (" << ev_time << " : " << end << ")" << std::endl;
|
||||
//cerr << "MRB: PAST END (" << ev_time << " : " << end << ")" << endl;
|
||||
break;
|
||||
} else if (ev_time < start) {
|
||||
//std::cerr << "MRB (start " << start << ") - Skipping event at (too early) time " << ev_time << std::endl;
|
||||
//cerr << "MRB (start " << start << ") - Skipping event at (too early) time " << ev_time << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
bool success = read_prefix(&ev_time, &ev_type, &ev_size);
|
||||
if (!success) {
|
||||
std::cerr << "WARNING: error reading event prefix from MIDI ring" << std::endl;
|
||||
cerr << "WARNING: error reading event prefix from MIDI ring" << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -68,7 +70,6 @@ MidiRingBuffer::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes_t
|
||||
ev_time += offset;
|
||||
Evoral::MIDIEvent loopevent(LoopEventType, ev_time);
|
||||
dst.push_back(loopevent);
|
||||
|
||||
|
||||
// We can safely return, without reading the data, because
|
||||
// a LoopEvent does not have data.
|
||||
@@ -83,15 +84,15 @@ MidiRingBuffer::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes_t
|
||||
if (is_channel_event(status) && get_channel_mode() == FilterChannels) {
|
||||
const uint8_t channel = status & 0x0F;
|
||||
if ( !(get_channel_mask() & (1L << channel)) ) {
|
||||
//std::cerr << "MRB skipping event due to channel mask" << std::endl;
|
||||
//cerr << "MRB skipping event due to channel mask" << endl;
|
||||
skip(ev_size); // Advance read pointer to next event
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//std::cerr << "MRB " << this << " - Reading event, time = "
|
||||
//cerr << "MRB " << this << " - Reading event, time = "
|
||||
// << ev_time << " - " << start << " => " << ev_time - start
|
||||
// << ", size = " << ev_size << std::endl;
|
||||
// << ", size = " << ev_size << endl;
|
||||
|
||||
assert(ev_time >= start);
|
||||
ev_time -= start;
|
||||
@@ -99,7 +100,7 @@ MidiRingBuffer::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes_t
|
||||
|
||||
uint8_t* write_loc = dst.reserve(ev_time, ev_size);
|
||||
if (write_loc == NULL) {
|
||||
//std::cerr << "MRB: Unable to reserve space in buffer, event skipped";
|
||||
//cerr << "MRB: Unable to reserve space in buffer, event skipped";
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -110,13 +111,13 @@ MidiRingBuffer::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes_t
|
||||
write_loc[0] = (write_loc[0] & 0xF0) | (get_channel_mask() & 0x0F);
|
||||
}
|
||||
++count;
|
||||
//std::cerr << "MRB - read event at time " << ev_time << std::endl;
|
||||
//cerr << "MRB - read event at time " << ev_time << endl;
|
||||
} else {
|
||||
std::cerr << "WARNING: error reading event contents from MIDI ring" << std::endl;
|
||||
//cerr << "WARNING: error reading event contents from MIDI ring" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
//std::cerr << "MTB read space: " << read_space() << std::endl;
|
||||
//cerr << "MTB read space: " << read_space() << endl;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -427,6 +427,8 @@ MidiTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_fram
|
||||
|
||||
passthru (start_frame, end_frame, nframes, offset, 0, (_meter_point == MeterInput));
|
||||
}
|
||||
|
||||
flush_outputs( nframes, offset );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -725,11 +727,11 @@ MidiTrack::midi_panic()
|
||||
bool
|
||||
MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
|
||||
{
|
||||
printf("Write immediate event: ");
|
||||
/*printf("Write immediate event: ");
|
||||
for (size_t i=0; i < size; ++i) {
|
||||
printf("%X ", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
printf("\n");*/
|
||||
const uint32_t type = EventTypeMap::instance().midi_event_type(buf[0]);
|
||||
return (_immediate_events.write(0, type, size, buf) == size);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user