Changes in Kinect SDK Beta 2

blamed_rachel

To celebrate the one year anniversary of the Kinect, Microsoft has launched a new Kinect website and released the Beta 2 version of the Kinect for Windows SDK: http://www.kinectforwindows.org/ .

This is not the commercial license we have been waiting for (it is reported to be coming in early 2012) but truly the next best thing.  The Beta 2 SDK introduces many performance improvements over the Beta 1 that was released in June. 

With the improvements also come some alterations to the basic syntax for instantiating the core objects of both the Nui and Audio namespaces, though these changes also have side-effects that will likely affect your code.  In particular, I want to cover one substantial change in the Nui namespace and one substantial change in the Audio namespace.

In the Beta 1, it was standard to instantiate a Nui.Runtime object in order to configure applications to read the depth, color and skeleton streams.  In a WPF application, the code looked like this:

        Microsoft.Research.Kinect.Nui.Runtime _nui;

        public MainWindow()
        {
            InitializeComponent();

            this.Unloaded += (s,e) => _nui.Uninitialize();
            _nui = new Runtime();

            _nui.Initialize(RuntimeOptions.UseColor 
                | RuntimeOptions.UseDepth);
            _nui.VideoFrameReady += _nui_VideoFrameReady;
            _nui.DepthFrameReady += _nui_DepthFrameReady;

            _nui.VideoStream.Open(ImageStreamType.Video, 2
                , ImageResolution.Resolution640x480
                , ImageType.Color);
            _nui.DepthStream.Open(ImageStreamType.Depth, 2
                , ImageResolution.Resolution320x240
                , ImageType.Depth);

        }

In the Beta 2, the Nui.Runtime has been obsoleted.  Instead, the Runtime type provides a static collection called Kinects that returns a Runtime object for each Kinect connected to the PC.    Additionally, in the new Beta, Runtime objects cannot be configured and used in the Initialize method as was possible with the Beta 1.  Instead, this must be done in the Loaded event handler.  This has ended up breaking a lot of my Beta 1 code.  Fortunately the refactor is fairly easy.  The following code assumes there is only one Kinect sensor plugged into the PC. 

        Microsoft.Research.Kinect.Nui.Runtime _nui;

        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += (s, e) =>
                {
                _nui = Runtime.Kinects[0];
                _nui.Initialize(RuntimeOptions.UseColor);
                _nui.VideoFrameReady += _nui_VideoFrameReady;
                _nui.VideoStream.Open(ImageStreamType.Video
                , 2
                , ImageResolution.Resolution1280x1024
                , ImageType.Color);
                };
        }

A central difficulty in working with the audio namespace is that the DMO named the KinectAudioSource, which is as fundamental to audio processing for the Kinect as the Nui.Runtime is for video and skeletal processing, must be instantiated on a thread running in a multithreaded apartment model.  WPF applications, unfortunately, run in an STA thread.  This required a bit of additional wiring up in the Beta 1 to create the KinectAudioSource object on a separate thread.

With the Kinect for Windows SDK Beta 2, this is implicitly taken care of for us.  If you have already been working with the Beta 1 audio namespace, you will finally be able to take out the workarounds you created to program against the audio stream along with all the additional care required for dealing with a multithreaded application.

[Thanks to Clint Rutkas of Coding4Fun for correcting me on the difference between obsolescence and breaking changes. The new Runtime instantiation process is not technically a breaking change.]