-
-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API function to get macOS LocationID and Windows ContainerID of an USB device #107
Comments
Do you have some sample code of how to do this ? |
For macOS you need to get the For Windows you need to get the |
Thanks. Now I have to find how I get these device nodes in MS Windows, as right now the code does not use these APIs AFAIK. |
I'm revisiting this and am wondering: port_information already stores the MIDIObjectRef's UUID so you can get it back in the following way (typing this without access to macOS so likely there are some mistakes but you get the gist): int32_t usb_id_from_port(const libremidi::port_information& info) {
// Get the MIDI object from the uid
auto uid = std::bit_cast<std::int32_t>((uint32_t)info.port);
MIDIObjectRef object{};
MIDIObjectType type{};
auto ret = MIDIObjectFindByUniqueID(uid, &object, &type);
assert(type == kMIDIObjectType_Source || type == kMIDIObjectType_Destination);
// Get the MIDI entity from the object
MIDIEntityRef entity{};
MIDIEndpointGetEntity(object, &entity);
if(!entity)
throw; // It means it's not a hardware port
// Get the MIDI device from the entity
MIDIDeviceRef device{};
MIDIEntityGetDevice(entity, &device);
if(!device)
throw;
SInt32 res{};
MIDIObjectGetIntegerProperty(device, CFSTR("USBDeviceID"), &res);
return res;
} For Windows I investigated but I see absolutely no way to get the device ID from the WinMM API. :/ |
What about this approach: #include <windows.h>
#include <setupapi.h>
#include <devpkey.h>
#include <iostream>
#include <string>
#include <initguid.h>
#pragma comment(lib, "setupapi.lib")
void CheckMidiDevices() {
// Get the device information set for all MIDI devices
HDEVINFO deviceInfoSet = SetupDiGetClassDevs(NULL, "SWD\\MMDEVAPI\\{0.0.1.00000000}.{00000000-0000-0000-0000-000000000000}", NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES);
if (deviceInfoSet == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to get device information set." << std::endl;
return;
}
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
// Enumerate through all devices in the set
for (DWORD i = 0; SetupDiEnumDeviceInfo(deviceInfoSet, i, &deviceInfoData); ++i) {
// Get the device instance ID
char deviceInstanceId[MAX_DEVICE_ID_LEN];
if (CM_Get_Device_ID(deviceInfoData.DevInst, deviceInstanceId, MAX_DEVICE_ID_LEN, 0) != CR_SUCCESS) {
continue;
}
// Get the device description
char deviceDescription[256];
if (SetupDiGetDeviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_DEVICEDESC, NULL, (PBYTE)deviceDescription, sizeof(deviceDescription), NULL)) {
std::cout << "Device: " << deviceDescription << std::endl;
}
// Get the ContainerID
DEVPROPTYPE propType;
GUID containerId;
if (SetupDiGetDeviceProperty(deviceInfoSet, &deviceInfoData, &DEVPKEY_Device_ContainerId, &propType, (PBYTE)&containerId, sizeof(containerId), NULL, 0)) {
LPOLESTR guidString;
StringFromCLSID(containerId, &guidString);
std::wcout << L"ContainerID: " << guidString << std::endl;
CoTaskMemFree(guidString);
}
// Get the device's parent to determine the connection type
DEVINST parentDevInst;
if (CM_Get_Parent(&parentDevInst, deviceInfoData.DevInst, 0) == CR_SUCCESS) {
char parentDeviceInstanceId[MAX_DEVICE_ID_LEN];
if (CM_Get_Device_ID(parentDevInst, parentDeviceInstanceId, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS) {
// Check if the parent device is a USB or Bluetooth device
if (strstr(parentDeviceInstanceId, "USB") != NULL) {
std::cout << "Connection Type: USB" << std::endl;
} else if (strstr(parentDeviceInstanceId, "BTH") != NULL) {
std::cout << "Connection Type: Bluetooth" << std::endl;
} else {
std::cout << "Connection Type: Other" << std::endl;
}
}
}
}
// Clean up
SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
int main() {
CheckMidiDevices();
return 0;
} |
hm but do we know for sure that the index of
is the same index than the one used by WinMM to enumerate MIDI devices ? |
especially in "borderline" cases where we plug multiple identical MIDI devices which have historically been iffy in winmm |
I don't know unfortunately. |
For compound USB devices, that have not only a MIDI interface, but interfaces used with other USB device classes (e.g. a display) as well, it is needed to group them. The operating systems macOS and Windows provide identifiers for this purpose:
It would be nice, if the libremidi API would provide getters, to get these IDs for an USB device.
The text was updated successfully, but these errors were encountered: