Search code examples
cameramicrophoneazurekinect

Using 2 Azure Kinect, how to figure out which microphone array belongs to which Azure Kinect?


I'm writing a software to record video and audio streams from two Microsoft Azure Kinect connected to one computer. As I want to join the audio and video stream from the devices I have to figure out, which microphone array belongs to which camera. With the base container id, I could already see the parts of the Azure Kinect and bring them together (4K camera, IR camera, microphone array). But I don't see a programmatic way (c or c++).

Environment: Azure Kinect SDK 1.4.1 / Win 10

What happened until now: With the k4a SDK it is easily possible to get the video data from the cameras (RGB+IR), but the SDK does not provide means to access the microphone arrays. So I used WASAPI and the multimedia API for the audio streams.

And from Oleg's Answer I learned how to find the ContainerIDs from the Azure Kinect. There I could also see the serial number in the DeviceInstanceID.

The source code below is minimal and does neither include error checking nor output to the screen

unsigned i=0
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
TCHAR szDeviceInstanceID[MAX_DEVICE_ID_LEN];
TCHAR szDesc[1024], szHardwareIDs[4096];
WCHAR szBuffer[4096];


// loop through devices, i as number in list
   DeviceInfoData.cbSize = sizeof(DeviceInfoData);
   SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData));
   CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID, MAX_PATH, 0);
   // put here code to display szDeviceInstanceID 
   
   SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC,
            &dwPropertyRegDataType, (BYTE*)szDesc, sizeof(szDesc), &dwSize));
   // put here code to display szDesc
   // ...
          fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData,
                &DEVPKEY_Device_BusReportedDeviceDesc,
                &ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0);
          // put here code to display szBuffer (with BusReportedDeviceDesc)
          fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData,
                &DEVPKEY_Device_BaseContainerId,
                &ulPropertyType, (BYTE*)szDesc, sizeof(szDesc), &dwSize, 0);
          StringFromGUID2((REFGUID)szDesc, szBuffer, ARRAY_SIZE(szBuffer));
          // put here code to display szBuffer (BaseContainerId)
// end of loop

will output something like this:

DeviceInstanceID ----USB\VID_045E&PID_097D&MI_02\8&904C5FF&0&0002
    Device Description: WinUsb Device
    Bus Reported Device Description: Azure Kinect 4K Camera
    BaseContainerId: {A60ED20F-7C3B-4B20-AF2F-77E5987FC5E0}


DeviceInstanceID ----USB\VID_045E&PID_097C\000591600112
    Device Description: WinUsb Device
    Bus Reported Device Description: Azure Kinect Depth Camera
    BaseContainerId: {A60ED20F-7C3B-4B20-AF2F-77E5987FC5E0}


DeviceInstanceID ----USB\VID_045E&PID_097D&MI_00\8&904C5FF&0&0000
    Device Description: USB Video Device
    Bus Reported Device Description: Azure Kinect 4K Camera
    BaseContainerId: {A60ED20F-7C3B-4B20-AF2F-77E5987FC5E0}


DeviceInstanceID ----USB\VID_045E&PID_097E&MI_00\8&177D8328&0&0000
    Device Description: USB Audio 2.0
    Bus Reported Device Description: Azure Kinect Microphone Array
    BaseContainerId: {A60ED20F-7C3B-4B20-AF2F-77E5987FC5E0}

All this refers to one Azure Kinect (one BaseContainerId). And the serial number from the Azure Kinect is part of the second DeviceInstanceID (000591600112). The data from the second Azure Kinect is not include here. It is similar but with another BaseContainerId and serial number.

With the k4a SDK function k4a_device_get_serialnum() I could get the serial numbers of the kinects.

To find the Azure Kinect Microphone Arrays I checked the AudioEndpoints via

    IMMDeviceEnumerator *deviceEnumerator = NULL;
    IMMDeviceCollection *deviceCollection = NULL;
    IMMDevice *device = NULL;

    CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, 
                     IID_PPV_ARGS(&deviceEnumerator);
    deviceEnumerator->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE,
                     &deviceCollection);
    // loop through devices (i)
            LPWSTR deviceName;
            deviceName = GetDeviceName(deviceCollection, i);
            device->GetId(&deviceid); 
            device->OpenPropertyStore(STGM_READ,&propstore);
            propstore->GetValue(PKEY_Device_FriendlyName ,&propvari);
            // check for Azure Kinect Microphone Array

and it will produce something like this

device name:Microphone Array (Azure Kinect Microphone Array) 
                       ({0.0.1.00000000}.{002466ae-4a3f-432c-8bae-1c3ddc8fc1f8})

device name:Microphone Array (2- Azure Kinect Microphone Array) 
                       ({0.0.1.00000000}.{0ae6a82f-5a3f-4ece-a618-80aafecb8fe8})

device name:Microphone Array (Realtek(R) Audio) 
                       ({0.0.1.00000000}.{b279e826-ffb8-465e-87d8-fe40db70cdf3})

I already checked for all types of GUID and ID in the multimedia and the device properties part but didn't see the way how to make loose ends meet. I hope it will be much simpler than what I do and would be glad to get some hint on how to pick the correct microphone array.


Solution

  • Try the below sample function snippet, be sure to test it from your side... Somehow i am not able to format the code in this editor, so pasting it image format. Hoping this may help somewhat....

    enter image description here