Share via


Setting up the Kinect as a Capture Device

Kinect for Windows 1.5, 1.6, 1.7, 1.8

Acquiring the Kinect

The Audio Capture Raw-Console sample's entry point is wmain in AudioCaptureRaw.cpp. This function manages the overall program execution, with private functions handling most of the details. WASAPI is COM-based, so the sample first initializes COM as follows:

int wmain()
{
   ...
   HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
   ...
}
    

The audio capture and remixing will be performed on a dedicated thread to reduce the chance of losing audio data.

Create the NuiSensor object

The Audio Capture Raw-Console sample next calls the CreateFirstConnected method, as follows:

HRESULT CreateFirstConnected(INuiSensor **ppNuiSensor)
{
   INuiSensor *pNuiSensor = NULL;
   int iSensorCount = 0;
   HRESULT hr = S_OK;

   *ppNuiSensor = NULL;

   hr = NuiGetSensorCount(& iSensorCount);

   // Look at each Kinect sensor
   for (int i = 0; i < iSensorCount; ++i)
   {
      // Create the sensor so we can check status, if we can't create it, move on to the next
      hr = NuiCreateSensorByIndex(i, & pNuiSensor);
      if (FAILED(hr))
      {
         continue;
      }

      // Get the status of the sensor, and if connected, then we can initialize it
      hr = pNuiSensor->NuiStatus();
      if (S_OK == hr)
      {
         *ppNuiSensor = pNuiSensor;
         pNuiSensor = NULL;
         break;
      }

      // This sensor wasn't OK, so release it since we're not using it
      SafeRelease(pNuiSensor);
   }

   if (SUCCEEDED(hr) && (NULL == *ppNuiSensor))
   {
      // If nothing went wrong but we haven't found a sensor, return failure
      hr = E_FAIL;
   }

   SafeRelease(pNuiSensor);
   return hr;
}
        

This is the standard way of looking for the first free Kinect sensor when multiple sensors may be attached at the same time. This code appears in all C++ samples.

Create the Kinect as a Windows Audio Device

GetMatchingAudioDevice then sets the Kinect up as a Windows audio device. The calling code in wmain is:

hr = GetMatchingAudioDevice(pNuiSensor, &device);
      

The GetMatchingAudioDevice method is:

HRESULT GetMatchingAudioDevice(INuiSensor *pNuiSensor, IMMDevice **ppDevice)
{
     IMMDeviceEnumerator *pDeviceEnumerator = NULL;
     IMMDeviceCollection *pDdeviceCollection = NULL;
     HRESULT hr = S_OK;

     *ppDevice = NULL;

     hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDeviceEnumerator ));
     hr = pDeviceEnumerator->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE, &pDdeviceCollection);
     UINT deviceCount;
     hr = pDdeviceCollection->GetCount(&deviceCount);
     // Iterate through all active audio capture devices looking for one that matches
     // the specified Kinect sensor.
     for (UINT i = 0 ; i < deviceCount; ++i)
     {
         IMMDevice *pDevice = NULL;
         hr = pDdeviceCollection->Item(i, &pDevice);
         if (SUCCEEDED(hr))
         {
           wchar_t *pszGlobalId = NULL;
           hr = GetGlobalId(pDevice, &pszGlobalId);
           if (SUCCEEDED(hr) && IsMatchingAudioDevice(pNuiSensor, pszGlobalId))
           {
              *ppDevice = pDevice;
              break;
           }

         }
     }     
}
      

This method uses the standard Windows multimedia device enumeration interface (IMMDeviceEnumerator) to find all audio devices connected to the computer, and then calls the IsMatchingAudioDevice method (code below) to find the Kinect's USB ID in the list of audio devices. Once the Kinect is found and identified as a Windows audio device, audio capture can start.

The IsMatchingAudioDevice method looks like this:

bool IsMatchingAudioDevice(INuiSensor *pNuiSensor, wchar_t *pszGlobalId)
{
      // Get USB device name from the sensor
      BSTR arrayName = pNuiSensor->NuiAudioArrayId(); // e.g. "USB\\VID_045E&PID_02BB&MI_02\\7&9FF7F87&0&0002"

      wistring strDeviceName(pszGlobalId); // e.g. "{2}.\\\\?\\usb#vid_045e&pid_02bb&mi_02#7&9ff7f87&0&0002#{6994ad04-93ef-11d0-a3cc-00a0c9223196}\\global/00010001"
      wistring strArrayName(arrayName);

      // Make strings have the same internal delimiters
      wistring::size_type findIndex = strArrayName.find(L'\\');
      while (strArrayName.npos != findIndex)
      {
         strArrayName[findIndex] = L'#';
         findIndex = strArrayName.find(L'\\', findIndex + 1);
      }

      // Try to match USB part names for sensor vs audio device global ID
      bool match = strDeviceName.find(strArrayName) != strDeviceName.npos;

      SysFreeString(arrayName);
      return match;
}