Merge pull request #86620 from fbcosentino/midi_device_id
Add MIDI controller device index to `InputEventMIDI.device` property.
This commit is contained in:
commit
8a3a559023
|
@ -42,9 +42,10 @@ void MIDIDriver::set_singleton() {
|
||||||
singleton = this;
|
singleton = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MIDIDriver::receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_t length) {
|
void MIDIDriver::receive_input_packet(int device_index, uint64_t timestamp, uint8_t *data, uint32_t length) {
|
||||||
Ref<InputEventMIDI> event;
|
Ref<InputEventMIDI> event;
|
||||||
event.instantiate();
|
event.instantiate();
|
||||||
|
event->set_device(device_index);
|
||||||
uint32_t param_position = 1;
|
uint32_t param_position = 1;
|
||||||
|
|
||||||
if (length >= 1) {
|
if (length >= 1) {
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
|
|
||||||
virtual PackedStringArray get_connected_inputs();
|
virtual PackedStringArray get_connected_inputs();
|
||||||
|
|
||||||
static void receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_t length);
|
static void receive_input_packet(int device_index, uint64_t timestamp, uint8_t *data, uint32_t length);
|
||||||
|
|
||||||
MIDIDriver();
|
MIDIDriver();
|
||||||
virtual ~MIDIDriver() {}
|
virtual ~MIDIDriver() {}
|
||||||
|
|
|
@ -82,13 +82,13 @@ size_t MIDIDriverALSAMidi::msg_expected_data(uint8_t status_byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MIDIDriverALSAMidi::InputConnection::parse_byte(uint8_t byte, MIDIDriverALSAMidi &driver,
|
void MIDIDriverALSAMidi::InputConnection::parse_byte(uint8_t byte, MIDIDriverALSAMidi &driver,
|
||||||
uint64_t timestamp) {
|
uint64_t timestamp, int device_index) {
|
||||||
switch (msg_category(byte)) {
|
switch (msg_category(byte)) {
|
||||||
case MessageCategory::RealTime:
|
case MessageCategory::RealTime:
|
||||||
// Real-Time messages are single byte messages that can
|
// Real-Time messages are single byte messages that can
|
||||||
// occur at any point.
|
// occur at any point.
|
||||||
// We pass them straight through.
|
// We pass them straight through.
|
||||||
driver.receive_input_packet(timestamp, &byte, 1);
|
driver.receive_input_packet(device_index, timestamp, &byte, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MessageCategory::Data:
|
case MessageCategory::Data:
|
||||||
|
@ -100,7 +100,7 @@ void MIDIDriverALSAMidi::InputConnection::parse_byte(uint8_t byte, MIDIDriverALS
|
||||||
|
|
||||||
// Forward a complete message and reset relevant state.
|
// Forward a complete message and reset relevant state.
|
||||||
if (received_data == expected_data) {
|
if (received_data == expected_data) {
|
||||||
driver.receive_input_packet(timestamp, buffer, received_data + 1);
|
driver.receive_input_packet(device_index, timestamp, buffer, received_data + 1);
|
||||||
received_data = 0;
|
received_data = 0;
|
||||||
|
|
||||||
if (msg_category(buffer[0]) != MessageCategory::Voice) {
|
if (msg_category(buffer[0]) != MessageCategory::Voice) {
|
||||||
|
@ -130,13 +130,13 @@ void MIDIDriverALSAMidi::InputConnection::parse_byte(uint8_t byte, MIDIDriverALS
|
||||||
expected_data = msg_expected_data(byte);
|
expected_data = msg_expected_data(byte);
|
||||||
skipping_sys_ex = false;
|
skipping_sys_ex = false;
|
||||||
if (expected_data == 0) {
|
if (expected_data == 0) {
|
||||||
driver.receive_input_packet(timestamp, &byte, 1);
|
driver.receive_input_packet(device_index, timestamp, &byte, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int MIDIDriverALSAMidi::InputConnection::read_in(MIDIDriverALSAMidi &driver, uint64_t timestamp) {
|
int MIDIDriverALSAMidi::InputConnection::read_in(MIDIDriverALSAMidi &driver, uint64_t timestamp, int device_index) {
|
||||||
int ret;
|
int ret;
|
||||||
do {
|
do {
|
||||||
uint8_t byte = 0;
|
uint8_t byte = 0;
|
||||||
|
@ -147,7 +147,7 @@ int MIDIDriverALSAMidi::InputConnection::read_in(MIDIDriverALSAMidi &driver, uin
|
||||||
ERR_PRINT("snd_rawmidi_read error: " + String(snd_strerror(ret)));
|
ERR_PRINT("snd_rawmidi_read error: " + String(snd_strerror(ret)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parse_byte(byte, driver, timestamp);
|
parse_byte(byte, driver, timestamp, device_index);
|
||||||
}
|
}
|
||||||
} while (ret > 0);
|
} while (ret > 0);
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ void MIDIDriverALSAMidi::thread_func(void *p_udata) {
|
||||||
size_t connection_count = md->connected_inputs.size();
|
size_t connection_count = md->connected_inputs.size();
|
||||||
|
|
||||||
for (size_t i = 0; i < connection_count; i++) {
|
for (size_t i = 0; i < connection_count; i++) {
|
||||||
connections[i].read_in(*md, timestamp);
|
connections[i].read_in(*md, timestamp, (int)i);
|
||||||
}
|
}
|
||||||
|
|
||||||
md->unlock();
|
md->unlock();
|
||||||
|
|
|
@ -58,7 +58,7 @@ class MIDIDriverALSAMidi : public MIDIDriver {
|
||||||
rawmidi_ptr{ midi_in } {}
|
rawmidi_ptr{ midi_in } {}
|
||||||
|
|
||||||
// Read in and parse available data, forwarding any complete messages through the driver.
|
// Read in and parse available data, forwarding any complete messages through the driver.
|
||||||
int read_in(MIDIDriverALSAMidi &driver, uint64_t timestamp);
|
int read_in(MIDIDriverALSAMidi &driver, uint64_t timestamp, int device_index);
|
||||||
|
|
||||||
snd_rawmidi_t *rawmidi_ptr = nullptr;
|
snd_rawmidi_t *rawmidi_ptr = nullptr;
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class MIDIDriverALSAMidi : public MIDIDriver {
|
||||||
size_t expected_data = 0;
|
size_t expected_data = 0;
|
||||||
size_t received_data = 0;
|
size_t received_data = 0;
|
||||||
bool skipping_sys_ex = false;
|
bool skipping_sys_ex = false;
|
||||||
void parse_byte(uint8_t byte, MIDIDriverALSAMidi &driver, uint64_t timestamp);
|
void parse_byte(uint8_t byte, MIDIDriverALSAMidi &driver, uint64_t timestamp, int device_index);
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector<InputConnection> connected_inputs;
|
Vector<InputConnection> connected_inputs;
|
||||||
|
|
|
@ -39,8 +39,9 @@
|
||||||
|
|
||||||
void MIDIDriverCoreMidi::read(const MIDIPacketList *packet_list, void *read_proc_ref_con, void *src_conn_ref_con) {
|
void MIDIDriverCoreMidi::read(const MIDIPacketList *packet_list, void *read_proc_ref_con, void *src_conn_ref_con) {
|
||||||
MIDIPacket *packet = const_cast<MIDIPacket *>(packet_list->packet);
|
MIDIPacket *packet = const_cast<MIDIPacket *>(packet_list->packet);
|
||||||
|
int *device_index = static_cast<int *>(src_conn_ref_con);
|
||||||
for (UInt32 i = 0; i < packet_list->numPackets; i++) {
|
for (UInt32 i = 0; i < packet_list->numPackets; i++) {
|
||||||
receive_input_packet(packet->timeStamp, packet->data, packet->length);
|
receive_input_packet(*device_index, packet->timeStamp, packet->data, packet->length);
|
||||||
packet = MIDIPacketNext(packet);
|
packet = MIDIPacketNext(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +65,7 @@ Error MIDIDriverCoreMidi::open() {
|
||||||
for (int i = 0; i < sources; i++) {
|
for (int i = 0; i < sources; i++) {
|
||||||
MIDIEndpointRef source = MIDIGetSource(i);
|
MIDIEndpointRef source = MIDIGetSource(i);
|
||||||
if (source) {
|
if (source) {
|
||||||
MIDIPortConnectSource(port_in, source, (void *)this);
|
MIDIPortConnectSource(port_in, source, static_cast<void *>(&i));
|
||||||
connected_sources.insert(i, source);
|
connected_sources.insert(i, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
void MIDIDriverWinMidi::read(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
|
void MIDIDriverWinMidi::read(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
|
||||||
if (wMsg == MIM_DATA) {
|
if (wMsg == MIM_DATA) {
|
||||||
receive_input_packet((uint64_t)dwParam2, (uint8_t *)&dwParam1, 3);
|
receive_input_packet((int)dwInstance, (uint64_t)dwParam2, (uint8_t *)&dwParam1, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ Error MIDIDriverWinMidi::open() {
|
||||||
for (UINT i = 0; i < midiInGetNumDevs(); i++) {
|
for (UINT i = 0; i < midiInGetNumDevs(); i++) {
|
||||||
HMIDIIN midi_in;
|
HMIDIIN midi_in;
|
||||||
|
|
||||||
MMRESULT res = midiInOpen(&midi_in, i, (DWORD_PTR)read, (DWORD_PTR)this, CALLBACK_FUNCTION);
|
MMRESULT res = midiInOpen(&midi_in, i, (DWORD_PTR)read, (DWORD_PTR)i, CALLBACK_FUNCTION);
|
||||||
if (res == MMSYSERR_NOERROR) {
|
if (res == MMSYSERR_NOERROR) {
|
||||||
midiInStart(midi_in);
|
midiInStart(midi_in);
|
||||||
connected_sources.insert(i, midi_in);
|
connected_sources.insert(i, midi_in);
|
||||||
|
|
Loading…
Reference in New Issue