Skip to content

Commit e1d0fcb

Browse files
committed
Merge pull request #384 from ofTheo/bugfix-better-keep_alive
Bugfix for multiple K4W or 1473 devices needing keep_alive. Reviewed-by: Benn Snyder <[email protected]>
2 parents 935a998 + a05b6c7 commit e1d0fcb

File tree

3 files changed

+88
-12
lines changed

3 files changed

+88
-12
lines changed

src/freenect_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ typedef void (*fnusb_iso_cb)(freenect_device *dev, uint8_t *buf, int len);
4545

4646
#include "usb_libusb10.h"
4747

48+
//needed to set the led state for non 1414 devices - replaces keep_alive.c
49+
FN_INTERNAL int fnusb_set_led_alt(libusb_device_handle * dev, freenect_context * ctx, freenect_led_options state);
50+
4851
struct _freenect_context {
4952
freenect_loglevel log_level;
5053
freenect_log_cb log_cb;

src/tilt.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,9 @@ int freenect_set_tilt_degs(freenect_device *dev, double angle)
243243
return ret;
244244
}
245245

246-
#ifdef BUILD_AUDIO
247-
int freenect_set_led_alt(freenect_device *dev, freenect_led_options state)
248-
{
249-
freenect_context *ctx = dev->parent;
250246

247+
FN_INTERNAL int fnusb_set_led_alt(libusb_device_handle * dev, freenect_context * ctx, freenect_led_options state)
248+
{
251249
typedef enum {
252250
LED_ALT_OFF = 1,
253251
LED_ALT_BLINK_GREEN = 2,
@@ -283,12 +281,19 @@ int freenect_set_led_alt(freenect_device *dev, freenect_led_options state)
283281
unsigned char buffer[20];
284282
memcpy(buffer, &cmd, 20);
285283

286-
res = libusb_bulk_transfer(dev->usb_audio.dev, 0x01, buffer, 20, &transferred, 0);
284+
res = libusb_bulk_transfer(dev, 0x01, buffer, 20, &transferred, 0);
287285
if (res != 0) {
288-
FN_WARNING("freenect_set_led_alt(): libusb_bulk_transfer failed: %d (transferred = %d)\n", res, transferred);
286+
FN_WARNING("fnusb_set_led_alt(): libusb_bulk_transfer failed: %d (transferred = %d)\n", res, transferred);
289287
return res;
290288
}
291-
return get_reply(dev->usb_audio.dev, ctx);
289+
return get_reply(dev, ctx);
290+
}
291+
292+
#ifdef BUILD_AUDIO
293+
int freenect_set_led_alt(freenect_device *dev, freenect_led_options state)
294+
{
295+
freenect_context *ctx = dev->parent;
296+
return fnusb_set_led_alt(dev->usb_audio.dev, ctx, state);
292297
}
293298
#endif
294299

src/usb_libusb10.c

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
171208
FN_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

Comments
 (0)