diff options
author | Ibrahn Sahir <ibrahn.sahir@gmail.com> | 2024-04-10 10:50:28 +0100 |
---|---|---|
committer | Ibrahn Sahir <ibrahn.sahir@gmail.com> | 2024-06-25 16:46:30 +0100 |
commit | 607c5ec49f605966c6870e34cebcd2f967be12d3 (patch) | |
tree | 5a23b3a590a8518fe6ec4cd0d667adb3afa72fdb /drivers/winmidi | |
parent | 6b281c0c07b07f2142b1fc8a6b3158091a9b124c (diff) | |
download | redot-engine-607c5ec49f605966c6870e34cebcd2f967be12d3.tar.gz |
Move MIDI parsing up from ALSA driver to platform independent driver.
Aims for more consistent MIDI support across Windows, MacOS, Linux and
to provide a base for adding MIDI drivers for other platforms.
Reworks the MIDIDriverALSAMidi MIDI parsing implementation as a platform
independent version in MIDIDriver::Parser.
Uses MIDIDriver::Parser to provide running status support in MacOS
MIDIDriverCoreMidi.
Collects connected input names at open, ensuring devices indices reported
in events match names in array returned from get_connected_inputs.
Fixes #77035.
Fixes #79811.
With code review changes by: A Thousand Ships (she/her)
<96648715+AThousandShips@users.noreply.github.com>
Diffstat (limited to 'drivers/winmidi')
-rw-r--r-- | drivers/winmidi/midi_driver_winmidi.cpp | 55 | ||||
-rw-r--r-- | drivers/winmidi/midi_driver_winmidi.h | 8 |
2 files changed, 28 insertions, 35 deletions
diff --git a/drivers/winmidi/midi_driver_winmidi.cpp b/drivers/winmidi/midi_driver_winmidi.cpp index 07f0226c5d..0f37f63ccd 100644 --- a/drivers/winmidi/midi_driver_winmidi.cpp +++ b/drivers/winmidi/midi_driver_winmidi.cpp @@ -36,26 +36,42 @@ void MIDIDriverWinMidi::read(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { if (wMsg == MIM_DATA) { - receive_input_packet((int)dwInstance, (uint64_t)dwParam2, (uint8_t *)&dwParam1, 3); + // For MIM_DATA: dwParam1 = wMidiMessage, dwParam2 = dwTimestamp. + // Windows implementation has already unpacked running status and dropped any SysEx, + // so we can just forward straight to the event. + const uint8_t *midi_msg = (uint8_t *)&dwParam1; + send_event((int)dwInstance, midi_msg[0], &midi_msg[1], 2); } } Error MIDIDriverWinMidi::open() { + int device_index = 0; for (UINT i = 0; i < midiInGetNumDevs(); i++) { HMIDIIN midi_in; + MIDIINCAPS caps; - MMRESULT res = midiInOpen(&midi_in, i, (DWORD_PTR)read, (DWORD_PTR)i, CALLBACK_FUNCTION); - if (res == MMSYSERR_NOERROR) { + MMRESULT open_res = midiInOpen(&midi_in, i, (DWORD_PTR)read, + (DWORD_PTR)device_index, CALLBACK_FUNCTION); + MMRESULT caps_res = midiInGetDevCaps(i, &caps, sizeof(MIDIINCAPS)); + + if (open_res == MMSYSERR_NOERROR) { midiInStart(midi_in); - connected_sources.insert(i, midi_in); + connected_sources.push_back(midi_in); + if (caps_res == MMSYSERR_NOERROR) { + connected_input_names.push_back(caps.szPname); + } else { + // Should push something even if we don't get a name, + // so that the IDs line up correctly on the script side. + connected_input_names.push_back("ERROR"); + } + // Only increment device index for successfully connected devices. + device_index++; } else { char err[256]; - midiInGetErrorText(res, err, 256); + midiInGetErrorText(open_res, err, 256); ERR_PRINT("midiInOpen error: " + String(err)); - MIDIINCAPS caps; - res = midiInGetDevCaps(i, &caps, sizeof(MIDIINCAPS)); - if (res == MMSYSERR_NOERROR) { + if (caps_res == MMSYSERR_NOERROR) { ERR_PRINT("Can't open MIDI device \"" + String(caps.szPname) + "\", is it being used by another application?"); } } @@ -64,25 +80,6 @@ Error MIDIDriverWinMidi::open() { return OK; } -PackedStringArray MIDIDriverWinMidi::get_connected_inputs() { - PackedStringArray list; - - for (int i = 0; i < connected_sources.size(); i++) { - HMIDIIN midi_in = connected_sources[i]; - UINT id = 0; - MMRESULT res = midiInGetID(midi_in, &id); - if (res == MMSYSERR_NOERROR) { - MIDIINCAPS caps; - res = midiInGetDevCaps(i, &caps, sizeof(MIDIINCAPS)); - if (res == MMSYSERR_NOERROR) { - list.push_back(caps.szPname); - } - } - } - - return list; -} - void MIDIDriverWinMidi::close() { for (int i = 0; i < connected_sources.size(); i++) { HMIDIIN midi_in = connected_sources[i]; @@ -90,9 +87,7 @@ void MIDIDriverWinMidi::close() { midiInClose(midi_in); } connected_sources.clear(); -} - -MIDIDriverWinMidi::MIDIDriverWinMidi() { + connected_input_names.clear(); } MIDIDriverWinMidi::~MIDIDriverWinMidi() { diff --git a/drivers/winmidi/midi_driver_winmidi.h b/drivers/winmidi/midi_driver_winmidi.h index f3e016f378..7a75252233 100644 --- a/drivers/winmidi/midi_driver_winmidi.h +++ b/drivers/winmidi/midi_driver_winmidi.h @@ -48,12 +48,10 @@ class MIDIDriverWinMidi : public MIDIDriver { static void CALLBACK read(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2); public: - virtual Error open(); - virtual void close(); + virtual Error open() override; + virtual void close() override; - virtual PackedStringArray get_connected_inputs(); - - MIDIDriverWinMidi(); + MIDIDriverWinMidi() = default; virtual ~MIDIDriverWinMidi(); }; |