summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Mayberry <mojofunk@gmail.com>2015-10-06 13:24:53 +1000
committerTim Mayberry <mojofunk@gmail.com>2015-10-06 13:29:57 +1000
commit4ebc6ef0b400b8db94635d2220124a642450ce60 (patch)
tree92a0234393521e157dbc59d9f0e319da0c59010b
parent1c0265e27c315d94cbbfc963ff153194fc4d6548 (diff)
Fix WinMME midi driver shutdown with sysex enabled
midiInReset triggers the sysex callback to tell the application that it has finished with the buffer. Calling midiInAddBuffer results in an infinite loop so just return during shutdown.
-rw-r--r--libs/backends/portaudio/winmmemidi_input_device.cc14
-rw-r--r--libs/backends/portaudio/winmmemidi_input_device.h1
2 files changed, 13 insertions, 2 deletions
diff --git a/libs/backends/portaudio/winmmemidi_input_device.cc b/libs/backends/portaudio/winmmemidi_input_device.cc
index 9fcee83efb..ed8f23b45e 100644
--- a/libs/backends/portaudio/winmmemidi_input_device.cc
+++ b/libs/backends/portaudio/winmmemidi_input_device.cc
@@ -37,6 +37,7 @@ namespace ARDOUR {
WinMMEMidiInputDevice::WinMMEMidiInputDevice (int index)
: m_handle(0)
, m_started(false)
+ , m_in_reset(false)
, m_midi_buffer(new RingBuffer<uint8_t>(MIDI_BUFFER_SIZE))
, m_sysex_buffer(new uint8_t[SYSEX_BUFFER_SIZE])
{
@@ -92,12 +93,14 @@ WinMMEMidiInputDevice::close (std::string& error_msg)
// return error message for first error encountered?
bool success = true;
+ m_in_reset = true;
MMRESULT result = midiInReset (m_handle);
if (result != MMSYSERR_NOERROR) {
error_msg = get_error_string (result);
DEBUG_MIDI (error_msg);
success = false;
}
+ m_in_reset = false;
result = midiInUnprepareHeader (m_handle, &m_sysex_header, sizeof(MIDIHDR));
if (result != MMSYSERR_NOERROR) {
error_msg = get_error_string (result);
@@ -258,12 +261,19 @@ WinMMEMidiInputDevice::handle_sysex_msg (MIDIHDR* const midi_header,
uint8_t* data = (uint8_t*)header->lpData;
- if ((data[0] != 0xf0) || (data[byte_count - 1] != 0xf7)) {
- DEBUG_MIDI (string_compose ("Discarding %1 byte sysex chunk\n", byte_count));
+ DEBUG_MIDI(string_compose("WinMME sysex flags: %1\n", header->dwFlags));
+
+ if (m_in_reset) {
+ DEBUG_MIDI(string_compose("Midi device %1 being reset ignoring sysex msg\n",
+ name()));
+ return;
+ } else if ((data[0] != 0xf0) || (data[byte_count - 1] != 0xf7)) {
+ DEBUG_MIDI(string_compose("Discarding %1 byte sysex chunk\n", byte_count));
} else {
enqueue_midi_msg (data, byte_count, timestamp);
}
+
MMRESULT result = midiInAddBuffer (m_handle, &m_sysex_header, sizeof(MIDIHDR));
if (result != MMSYSERR_NOERROR) {
DEBUG_MIDI (get_error_string (result));
diff --git a/libs/backends/portaudio/winmmemidi_input_device.h b/libs/backends/portaudio/winmmemidi_input_device.h
index b1a7fb6b88..06b8202f43 100644
--- a/libs/backends/portaudio/winmmemidi_input_device.h
+++ b/libs/backends/portaudio/winmmemidi_input_device.h
@@ -91,6 +91,7 @@ private: // data
MIDIHDR m_sysex_header;
bool m_started;
+ bool m_in_reset;
std::string m_name;