@@ -168,6 +168,43 @@ FN_INTERNAL int fnusb_is_pid_k4w_audio(int pid)
168168 return (pid == PID_K4W_AUDIO || pid == PID_K4W_AUDIO_ALT_1 || pid == PID_K4W_AUDIO_ALT_2 );
169169}
170170
171+ // fnusb_find_connected_audio_device uses new libusb features. we use guards to make sure its backwards compatible with older versions of libusb
172+ #if defined(LIBUSB_API_VERSION ) && (LIBUSB_API_VERSION >= 0x01000102 )
173+ FN_INTERNAL libusb_device * fnusb_find_connected_audio_device (libusb_device * camera , libusb_device * * deviceList , int cnt ){
174+
175+ int cameraBusNo = libusb_get_bus_number (camera );
176+ libusb_device * cameraParent = libusb_get_parent (camera );
177+
178+ if ( cameraBusNo < 0 ) return NULL ;
179+ if ( cnt <= 0 ) return NULL ;
180+
181+ int i = 0 ;
182+ struct libusb_device_descriptor desc ;
183+
184+ for (i = 0 ; i < cnt ; i ++ ) {
185+ int r = libusb_get_device_descriptor (deviceList [i ], & desc );
186+ if (r < 0 ) continue ;
187+ if (desc .idVendor != VID_MICROSOFT ) continue ;
188+
189+ //make sure its some type of Kinect audio device
190+ if ( (desc .idProduct == PID_NUI_AUDIO || fnusb_is_pid_k4w_audio (desc .idProduct ) ) ){
191+
192+ int audioBusNo = libusb_get_bus_number (deviceList [i ]);
193+ if ( audioBusNo == cameraBusNo ){
194+ //we have a match!
195+ //lets double check
196+ libusb_device * audioParent = libusb_get_parent (deviceList [i ]);
197+ if ( cameraParent == audioParent ){
198+ return deviceList [i ];
199+ }
200+ }
201+ }
202+ }
203+
204+ return NULL ;
205+ }
206+ #endif
207+
171208FN_INTERNAL int fnusb_open_subdevices (freenect_device * dev , int index )
172209{
173210 freenect_context * ctx = dev -> parent ;
@@ -214,27 +251,58 @@ FN_INTERNAL int fnusb_open_subdevices(freenect_device *dev, int index)
214251 dev -> usb_cam .dev = NULL ;
215252 break ;
216253 }
217- if (desc .idProduct == PID_K4W_CAMERA || desc .bcdDevice != fn_le32 (267 )) {
254+ if (desc .idProduct == PID_K4W_CAMERA || desc .bcdDevice != fn_le32 (267 )){
255+
218256 freenect_device_flags requested_devices = ctx -> enabled_subdevices ;
257+
258+
259+ /* Not the 1414 kinect so remove the motor flag, this should preserve the audio flag if set */
260+ ctx -> enabled_subdevices = (freenect_device_flags )(ctx -> enabled_subdevices & ~FREENECT_DEVICE_MOTOR );
219261
220- // Not the old kinect so we only set up the camera
221- ctx -> enabled_subdevices = FREENECT_DEVICE_CAMERA ;
222262 ctx -> zero_plane_res = 334 ;
223263 dev -> device_does_motor_control_with_audio = 1 ;
224264
265+ //lets also set the LED for non 1414 devices.
266+ //this keeps the camera alive for some systems which get freezes.
267+ //this code replaces keep_alive.c. As keep_alive.c didn't know which hub the connected audio device was on.
268+ //fnusb_find_connected_audio_device needs libusb 1.0.18 or later though.
269+
270+ #if defined(LIBUSB_API_VERSION ) && (LIBUSB_API_VERSION >= 0x01000102 )
271+ libusb_device * audioDevice = fnusb_find_connected_audio_device (devs [i ], devs , cnt );
272+ if ( audioDevice != NULL ){
273+
274+ libusb_device_handle * audioHandle = NULL ;
275+ res = libusb_open (audioDevice , & audioHandle );
276+
277+ if ( res != 0 ){
278+ FN_ERROR ("Failed to set the LED of K4W or 1473 device: %d\n" , res );
279+ }else {
280+ res = libusb_claim_interface (audioHandle , 0 );
281+ if ( res != 0 ){
282+ FN_ERROR ("Unable to claim interface %d\n" , res );
283+ }else {
284+ fnusb_set_led_alt (audioHandle , ctx , LED_GREEN );
285+ libusb_release_interface (audioHandle , 0 );
286+ }
287+ libusb_close (audioHandle );
288+ }
289+ }
290+ #else
291+ //Legacy: For older versions of libusb we use this approach which doesn't do well when multiple K4W or 1473 devices are attached to the system.
225292 //lets also set the LED ON
226293 //this keeps the camera alive for some systems which get freezes
227294 if ( desc .idProduct == PID_K4W_CAMERA ){
228295 freenect_extra_keep_alive (PID_K4W_AUDIO );
229296 }else {
230297 freenect_extra_keep_alive (PID_NUI_AUDIO );
231298 }
299+ #endif
300+
232301
233302#ifdef BUILD_AUDIO
234303 //for newer devices we need to enable the audio device for motor control
235304 //we only do this though if motor has been requested.
236- if ((requested_devices & FREENECT_DEVICE_MOTOR ) && (requested_devices & FREENECT_DEVICE_AUDIO ) == 0 )
237- {
305+ if ( (requested_devices & FREENECT_DEVICE_MOTOR ) && (requested_devices & FREENECT_DEVICE_AUDIO ) == 0 ){
238306 ctx -> enabled_subdevices = (freenect_device_flags )(ctx -> enabled_subdevices | FREENECT_DEVICE_AUDIO );
239307 }
240308#endif
0 commit comments