mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 00:04:56 +01:00
rework raw-midi drain strategy (workaround for sync devices)
This commit is contained in:
parent
157161e482
commit
bc67e47048
3 changed files with 30 additions and 6 deletions
|
|
@ -1429,7 +1429,7 @@ AlsaAudioBackend::main_process_thread ()
|
||||||
static_cast<AlsaMidiPort*>(*it)->next_period();
|
static_cast<AlsaMidiPort*>(*it)->next_period();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* queue midi*/
|
/* queue midi */
|
||||||
i = 0;
|
i = 0;
|
||||||
for (std::vector<AlsaPort*>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it, ++i) {
|
for (std::vector<AlsaPort*>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it, ++i) {
|
||||||
assert (_rmidi_out.size() > i);
|
assert (_rmidi_out.size() > i);
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ AlsaRawMidiIO::AlsaRawMidiIO (const char *device, const bool input)
|
||||||
AlsaRawMidiIO::~AlsaRawMidiIO ()
|
AlsaRawMidiIO::~AlsaRawMidiIO ()
|
||||||
{
|
{
|
||||||
if (_device) {
|
if (_device) {
|
||||||
|
snd_rawmidi_drain (_device);
|
||||||
snd_rawmidi_close (_device);
|
snd_rawmidi_close (_device);
|
||||||
_device = 0;
|
_device = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -243,6 +244,7 @@ AlsaRawMidiOut::main_process_thread ()
|
||||||
{
|
{
|
||||||
_running = true;
|
_running = true;
|
||||||
pthread_mutex_lock (&_notify_mutex);
|
pthread_mutex_lock (&_notify_mutex);
|
||||||
|
bool need_drain = false;
|
||||||
while (_running) {
|
while (_running) {
|
||||||
bool have_data = false;
|
bool have_data = false;
|
||||||
struct MidiEventHeader h(0,0);
|
struct MidiEventHeader h(0,0);
|
||||||
|
|
@ -269,13 +271,22 @@ AlsaRawMidiOut::main_process_thread ()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!have_data) {
|
if (!have_data) {
|
||||||
|
if (need_drain) {
|
||||||
|
snd_rawmidi_drain (_device);
|
||||||
|
need_drain = false;
|
||||||
|
}
|
||||||
pthread_cond_wait (&_notify_ready, &_notify_mutex);
|
pthread_cond_wait (&_notify_ready, &_notify_mutex);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t now = g_get_monotonic_time();
|
uint64_t now = g_get_monotonic_time();
|
||||||
while (h.time > now + 500) {
|
while (h.time > now + 500) {
|
||||||
select_sleep(h.time - now);
|
if (need_drain) {
|
||||||
|
snd_rawmidi_drain (_device);
|
||||||
|
need_drain = false;
|
||||||
|
} else {
|
||||||
|
select_sleep(h.time - now);
|
||||||
|
}
|
||||||
now = g_get_monotonic_time();
|
now = g_get_monotonic_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -309,7 +320,11 @@ retry:
|
||||||
|
|
||||||
ssize_t err = snd_rawmidi_write (_device, data, h.size);
|
ssize_t err = snd_rawmidi_write (_device, data, h.size);
|
||||||
|
|
||||||
if ((err == -EAGAIN) || (err == -EWOULDBLOCK)) {
|
if ((err == -EAGAIN)) {
|
||||||
|
snd_rawmidi_drain (_device);
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
if (err == -EWOULDBLOCK) {
|
||||||
select_sleep (1000);
|
select_sleep (1000);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
@ -323,7 +338,7 @@ retry:
|
||||||
h.size -= err;
|
h.size -= err;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
snd_rawmidi_drain (_device);
|
need_drain = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock (&_notify_mutex);
|
pthread_mutex_unlock (&_notify_mutex);
|
||||||
|
|
@ -472,6 +487,7 @@ int
|
||||||
AlsaRawMidiIn::queue_event (const uint64_t time, const uint8_t *data, const size_t size) {
|
AlsaRawMidiIn::queue_event (const uint64_t time, const uint8_t *data, const size_t size) {
|
||||||
const uint32_t buf_size = sizeof(MidiEventHeader) + size;
|
const uint32_t buf_size = sizeof(MidiEventHeader) + size;
|
||||||
_event._pending = false;
|
_event._pending = false;
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -488,6 +504,7 @@ AlsaRawMidiIn::queue_event (const uint64_t time, const uint8_t *data, const size
|
||||||
void
|
void
|
||||||
AlsaRawMidiIn::parse_events (const uint64_t time, const uint8_t *data, const size_t size) {
|
AlsaRawMidiIn::parse_events (const uint64_t time, const uint8_t *data, const size_t size) {
|
||||||
if (_event._pending) {
|
if (_event._pending) {
|
||||||
|
_DEBUGPRINT("AlsaRawMidiIn: queue pending event\n");
|
||||||
if (queue_event (_event._time, _parser_buffer, _event._size)) {
|
if (queue_event (_event._time, _parser_buffer, _event._size)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -533,6 +550,13 @@ AlsaRawMidiIn::process_byte(const uint64_t time, const uint8_t byte)
|
||||||
if (byte >= 0x80) {
|
if (byte >= 0x80) {
|
||||||
// Non-realtime status byte
|
// Non-realtime status byte
|
||||||
if (_total_bytes) {
|
if (_total_bytes) {
|
||||||
|
_DEBUGPRINT("AlsaRawMidiIn: discarded bogus midi message\n");
|
||||||
|
#if 0
|
||||||
|
for (size_t i=0; i < _total_bytes; ++i) {
|
||||||
|
printf("%02x ", _parser_buffer[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
_total_bytes = 0;
|
_total_bytes = 0;
|
||||||
_unbuffered_bytes = 0;
|
_unbuffered_bytes = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -591,7 +615,7 @@ AlsaRawMidiIn::process_byte(const uint64_t time, const uint8_t byte)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (! _total_bytes) {
|
if (! _total_bytes) {
|
||||||
// Apply running status.
|
_DEBUGPRINT("AlsaRawMidiIn: apply running status\n");
|
||||||
record_byte(_status_byte);
|
record_byte(_status_byte);
|
||||||
}
|
}
|
||||||
record_byte(byte);
|
record_byte(byte);
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool prepare_buffered_event(const uint64_t time) {
|
bool prepare_buffered_event(const uint64_t time) {
|
||||||
const bool result = !_unbuffered_bytes;
|
const bool result = _unbuffered_bytes == 0;
|
||||||
if (result) {
|
if (result) {
|
||||||
_event.prepare(time, _total_bytes);
|
_event.prepare(time, _total_bytes);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue