summaryrefslogtreecommitdiff
path: root/libs/backends
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2014-06-19 19:42:19 +0200
committerRobin Gareus <robin@gareus.org>2014-06-19 19:44:14 +0200
commitbc67e47048d5a9f30088787cef2860d91851a8d9 (patch)
treeaac3935b39ab0f0a84373fcfcc4f4085f27c42a5 /libs/backends
parent157161e48225e0ade5f626abdc293db2c5f9939d (diff)
rework raw-midi drain strategy (workaround for sync devices)
Diffstat (limited to 'libs/backends')
-rw-r--r--libs/backends/alsa/alsa_audiobackend.cc2
-rw-r--r--libs/backends/alsa/alsa_rawmidi.cc32
-rw-r--r--libs/backends/alsa/alsa_rawmidi.h2
3 files changed, 30 insertions, 6 deletions
diff --git a/libs/backends/alsa/alsa_audiobackend.cc b/libs/backends/alsa/alsa_audiobackend.cc
index 4fd83d6714..58780acf4e 100644
--- a/libs/backends/alsa/alsa_audiobackend.cc
+++ b/libs/backends/alsa/alsa_audiobackend.cc
@@ -1429,7 +1429,7 @@ AlsaAudioBackend::main_process_thread ()
static_cast<AlsaMidiPort*>(*it)->next_period();
}
- /* queue midi*/
+ /* queue midi */
i = 0;
for (std::vector<AlsaPort*>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it, ++i) {
assert (_rmidi_out.size() > i);
diff --git a/libs/backends/alsa/alsa_rawmidi.cc b/libs/backends/alsa/alsa_rawmidi.cc
index 00fc39a4cf..b3a5720aa2 100644
--- a/libs/backends/alsa/alsa_rawmidi.cc
+++ b/libs/backends/alsa/alsa_rawmidi.cc
@@ -57,6 +57,7 @@ AlsaRawMidiIO::AlsaRawMidiIO (const char *device, const bool input)
AlsaRawMidiIO::~AlsaRawMidiIO ()
{
if (_device) {
+ snd_rawmidi_drain (_device);
snd_rawmidi_close (_device);
_device = 0;
}
@@ -243,6 +244,7 @@ AlsaRawMidiOut::main_process_thread ()
{
_running = true;
pthread_mutex_lock (&_notify_mutex);
+ bool need_drain = false;
while (_running) {
bool have_data = false;
struct MidiEventHeader h(0,0);
@@ -269,13 +271,22 @@ AlsaRawMidiOut::main_process_thread ()
}
if (!have_data) {
+ if (need_drain) {
+ snd_rawmidi_drain (_device);
+ need_drain = false;
+ }
pthread_cond_wait (&_notify_ready, &_notify_mutex);
continue;
}
uint64_t now = g_get_monotonic_time();
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();
}
@@ -309,7 +320,11 @@ retry:
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);
goto retry;
}
@@ -323,7 +338,7 @@ retry:
h.size -= err;
goto retry;
}
- snd_rawmidi_drain (_device);
+ need_drain = true;
}
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) {
const uint32_t buf_size = sizeof(MidiEventHeader) + size;
_event._pending = false;
+
if (size == 0) {
return -1;
}
@@ -488,6 +504,7 @@ AlsaRawMidiIn::queue_event (const uint64_t time, const uint8_t *data, const size
void
AlsaRawMidiIn::parse_events (const uint64_t time, const uint8_t *data, const size_t size) {
if (_event._pending) {
+ _DEBUGPRINT("AlsaRawMidiIn: queue pending event\n");
if (queue_event (_event._time, _parser_buffer, _event._size)) {
return;
}
@@ -533,6 +550,13 @@ AlsaRawMidiIn::process_byte(const uint64_t time, const uint8_t byte)
if (byte >= 0x80) {
// Non-realtime status byte
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;
_unbuffered_bytes = 0;
}
@@ -591,7 +615,7 @@ AlsaRawMidiIn::process_byte(const uint64_t time, const uint8_t byte)
return false;
}
if (! _total_bytes) {
- // Apply running status.
+ _DEBUGPRINT("AlsaRawMidiIn: apply running status\n");
record_byte(_status_byte);
}
record_byte(byte);
diff --git a/libs/backends/alsa/alsa_rawmidi.h b/libs/backends/alsa/alsa_rawmidi.h
index eafdf07561..896ae07246 100644
--- a/libs/backends/alsa/alsa_rawmidi.h
+++ b/libs/backends/alsa/alsa_rawmidi.h
@@ -114,7 +114,7 @@ private:
}
bool prepare_buffered_event(const uint64_t time) {
- const bool result = !_unbuffered_bytes;
+ const bool result = _unbuffered_bytes == 0;
if (result) {
_event.prepare(time, _total_bytes);
}