X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libs%2Fbackends%2Fportaudio%2Fwinmmemidi_input_device.cc;h=4e0e84f468d5855367aaf77bf97dc4487148f178;hb=bb090c0012340b637508e0930376b3d5afba5f5c;hp=9fcee83efb4aa9dec47926bd1068f693f47f1b31;hpb=eb4c9b022aee1f8a6fdf6392b074dd53122067e9;p=ardour.git diff --git a/libs/backends/portaudio/winmmemidi_input_device.cc b/libs/backends/portaudio/winmmemidi_input_device.cc index 9fcee83efb..4e0e84f468 100644 --- a/libs/backends/portaudio/winmmemidi_input_device.cc +++ b/libs/backends/portaudio/winmmemidi_input_device.cc @@ -124,6 +124,7 @@ WinMMEMidiInputDevice::add_sysex_buffer (std::string& error_msg) { m_sysex_header.dwBufferLength = SYSEX_BUFFER_SIZE; m_sysex_header.dwFlags = 0; + m_sysex_header.dwBytesRecorded = 0; m_sysex_header.lpData = (LPSTR)m_sysex_buffer.get (); MMRESULT result = midiInPrepareHeader (m_handle, &m_sysex_header, sizeof(MIDIHDR)); @@ -138,6 +139,8 @@ WinMMEMidiInputDevice::add_sysex_buffer (std::string& error_msg) error_msg = get_error_string (result); DEBUG_MIDI (error_msg); return false; + } else { + DEBUG_MIDI ("Added Initial WinMME sysex buffer\n"); } return true; } @@ -206,19 +209,23 @@ WinMMEMidiInputDevice::winmm_input_callback(HMIDIIN handle, switch (msg) { case MIM_OPEN: case MIM_CLOSE: + DEBUG_MIDI("WinMME: devices changed callback\n"); // devices_changed_callback break; case MIM_MOREDATA: + DEBUG_MIDI("WinMME: more data ..\n"); // passing MIDI_IO_STATUS to midiInOpen means that MIM_MOREDATA // will be sent when the callback isn't processing MIM_DATA messages // fast enough to keep up with messages arriving at input device // driver. I'm not sure what could be done differently if that occurs // so just handle MIM_DATA as per normal case MIM_DATA: + DEBUG_MIDI(string_compose ("WinMME: short msg @ %1\n", (uint32_t) timestamp)); midi_input->handle_short_msg ((const uint8_t*)&midi_msg, (uint32_t)timestamp); break; case MIM_LONGDATA: - midi_input->handle_sysex_msg ((MIDIHDR*)&midi_msg, (uint32_t)timestamp); + DEBUG_MIDI(string_compose ("WinMME: long msg @ %1\n", (uint32_t) timestamp)); + midi_input->handle_sysex_msg ((MIDIHDR*)midi_msg, (uint32_t)timestamp); break; case MIM_ERROR: DEBUG_MIDI ("WinMME: Driver sent an invalid MIDI message\n"); @@ -226,6 +233,9 @@ WinMMEMidiInputDevice::winmm_input_callback(HMIDIIN handle, case MIM_LONGERROR: DEBUG_MIDI ("WinMME: Driver sent an invalid or incomplete SYSEX message\n"); break; + default: + DEBUG_MIDI ("WinMME: Driver sent an unknown message\n"); + break; } } @@ -247,26 +257,46 @@ void WinMMEMidiInputDevice::handle_sysex_msg (MIDIHDR* const midi_header, uint32_t timestamp) { - LPMIDIHDR header = (LPMIDIHDR)midi_header; - size_t byte_count = header->dwBytesRecorded; + size_t byte_count = midi_header->dwBytesRecorded; - if (!byte_count) { - DEBUG_MIDI ( - "ERROR: WinMME driver has returned sysex header to us with no bytes\n"); + if (byte_count == 0) { + if ((midi_header->dwFlags & WHDR_DONE) != 0) { + DEBUG_MIDI("WinMME: In midi reset\n"); + // unprepare handled by close + } else { + DEBUG_MIDI( + "ERROR: WinMME driver has returned sysex header to us with no bytes\n"); + } return; } - uint8_t* data = (uint8_t*)header->lpData; + uint8_t* data = (uint8_t*)midi_header->lpData; + + DEBUG_MIDI(string_compose("WinMME sysex flags: %1\n", midi_header->dwFlags)); 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("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)); + DEBUG_MIDI("Adding sysex buffer back to WinMME buffer pool\n"); + + midi_header->dwFlags = 0; + midi_header->dwBytesRecorded = 0; + + MMRESULT result = midiInPrepareHeader(m_handle, midi_header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { - DEBUG_MIDI (get_error_string (result)); + DEBUG_MIDI(string_compose("Unable to prepare header: %1\n", + get_error_string(result))); + return; + } + + result = midiInAddBuffer(m_handle, midi_header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + DEBUG_MIDI(string_compose("Unable to add sysex buffer to buffer pool : %1\n", + get_error_string(result))); } }