Update of /cvsroot/pure-data/externals/io/hidio In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8060
Modified Files: Makefile TODO hidio-help.pd hidio.c hidio.h hidio_darwin.c hidio_linux.c Log Message: added latency measuring code on Darwin (to be removed once testing is done), and removed threading
Index: hidio.h =================================================================== RCS file: /cvsroot/pure-data/externals/io/hidio/hidio.h,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** hidio.h 21 Dec 2006 18:40:59 -0000 1.11 --- hidio.h 31 Dec 2006 22:49:16 -0000 1.12 *************** *** 4,8 **** #include <stdio.h> #ifdef _WIN32 - #include "pthread.h" /* needs pthread library */ #define LOG_DEBUG 7 #define LOG_INFO 6 --- 4,7 ---- *************** *** 12,16 **** #else #include <sys/syslog.h> - #include <pthread.h> #endif /* _WIN32 */
--- 11,14 ---- *************** *** 68,73 ****
/* this is limited so that the object doesn't cause a click getting too many ! * events from the OS's event queue */ ! #define MAX_EVENTS_PER_POLL 64
/*------------------------------------------------------------------------------ --- 66,73 ----
/* this is limited so that the object doesn't cause a click getting too many ! * events from the OS's event queue. On Mac OS X, this is set in on the ! * kernel level in HID_Utilities_External.h with the constant ! * kDeviceQueueSize */ ! #define MAX_EVENTS_PER_POLL 50
/*------------------------------------------------------------------------------ *************** *** 94,104 **** #ifndef PD void *x_obex; ! #endif /* PD */ #ifdef _WIN32 HANDLE x_fd; ! #endif /* _WIN32 */ #ifdef __linux__ t_int x_fd; ! #endif /* __linux */ void *x_ff_device; short x_device_number; --- 94,104 ---- #ifndef PD void *x_obex; ! #endif #ifdef _WIN32 HANDLE x_fd; ! #endif #ifdef __linux__ t_int x_fd; ! #endif void *x_ff_device; short x_device_number; *************** *** 111,120 **** t_outlet *x_data_outlet; t_outlet *x_status_outlet; - t_int x_requestcode; - pthread_mutex_t x_mutex; - pthread_cond_t x_requestcondition; - pthread_cond_t x_answercondition; - pthread_t x_thread; - t_int x_priority; } t_hidio;
--- 111,114 ---- *************** *** 187,191 **** extern void hidio_build_device_list(void); extern void hidio_get_events(t_hidio *x); ! extern void hidio_doprint(t_hidio* x); /* print info to the console */ extern void hidio_platform_specific_info(t_hidio* x); /* device info on the status outlet */ extern void hidio_platform_specific_free(t_hidio *x); --- 181,185 ---- extern void hidio_build_device_list(void); extern void hidio_get_events(t_hidio *x); ! extern void hidio_print(t_hidio* x); /* print info to the console */ extern void hidio_platform_specific_info(t_hidio* x); /* device info on the status outlet */ extern void hidio_platform_specific_free(t_hidio *x);
Index: hidio.c =================================================================== RCS file: /cvsroot/pure-data/externals/io/hidio/hidio.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** hidio.c 21 Dec 2006 18:40:59 -0000 1.13 --- hidio.c 31 Dec 2006 22:49:16 -0000 1.14 *************** *** 88,92 **** static void hidio_open(t_hidio *x, t_symbol *s, int argc, t_atom *argv); //static t_int hidio_close(t_hidio *x); - //static t_int hidio_child_read(t_hidio *x); //static void hidio_float(t_hidio* x, t_floatarg f);
--- 88,91 ---- *************** *** 298,307 **** SETFLOAT(event_data + 1, output_data->instance); SETFLOAT(event_data + 2, output_data->value); ! #else atom_setsym(event_data, output_data->name); atom_setsym(event_data, output_data->name); atom_setlong(event_data + 1, (long)output_data->instance); atom_setlong(event_data + 2, (long)output_data->value); ! #endif outlet_anything(x->x_data_outlet, output_data->type, 3, event_data); } --- 297,306 ---- SETFLOAT(event_data + 1, output_data->instance); SETFLOAT(event_data + 2, output_data->value); ! #else /* Max */ atom_setsym(event_data, output_data->name); atom_setsym(event_data, output_data->name); atom_setlong(event_data + 1, (long)output_data->instance); atom_setlong(event_data + 2, (long)output_data->value); ! #endif /* PD */ outlet_anything(x->x_data_outlet, output_data->type, 3, event_data); } *************** *** 310,318 ****
/* stop polling the device */ ! static void stop_poll(t_hidio* x) { ! debug_print(LOG_DEBUG,"stop_poll");
- pthread_mutex_lock(&x->x_mutex); if (x->x_started) { --- 309,316 ----
/* stop polling the device */ ! static void hidio_stop_poll(t_hidio* x) { ! debug_print(LOG_DEBUG,"hidio_stop_poll");
if (x->x_started) { *************** *** 321,325 **** x->x_started = 0; } - pthread_mutex_unlock(&x->x_mutex); }
--- 319,322 ---- *************** *** 328,335 **** */
! void hidio_poll(t_hidio* x, t_float f) { - pthread_mutex_lock(&x->x_mutex); debug_print(LOG_DEBUG,"hidio_poll");
--- 325,334 ---- */
! /* TODO: poll time should be set based on how fast the OS is actually polling ! * the device, whether that is IOUSBEndpointDescriptor.bInterval, or something ! * else. ! */ void hidio_poll(t_hidio* x, t_float f) { debug_print(LOG_DEBUG,"hidio_poll");
*************** *** 343,349 **** if(!x->x_device_open) { - pthread_mutex_unlock(&x->x_mutex); hidio_open(x,ps_open,0,NULL); - pthread_mutex_lock(&x->x_mutex); } if(!x->x_started) --- 342,346 ---- *************** *** 354,363 **** } } - pthread_mutex_unlock(&x->x_mutex); }
static void hidio_set_from_float(t_hidio *x, t_floatarg f) { - pthread_mutex_lock(&x->x_mutex); /* values greater than 1 set the polling delay time */ /* 1 and 0 for start/stop so you can use a [tgl] */ --- 351,358 ---- *************** *** 365,371 **** { x->x_delay = (t_int)f; - pthread_mutex_unlock(&x->x_mutex); hidio_poll(x,f); - pthread_mutex_lock(&x->x_mutex); } else if(f == 1) --- 360,364 ---- *************** *** 373,388 **** if(! x->x_started) { - pthread_mutex_unlock(&x->x_mutex); hidio_poll(x,f); - pthread_mutex_lock(&x->x_mutex); } } else if(f == 0) { ! pthread_mutex_unlock(&x->x_mutex); ! stop_poll(x); ! pthread_mutex_lock(&x->x_mutex); } - pthread_mutex_unlock(&x->x_mutex); }
--- 366,376 ---- if(! x->x_started) { hidio_poll(x,f); } } else if(f == 0) { ! hidio_stop_poll(x); } }
*************** *** 392,399 **** debug_print(LOG_DEBUG,"hidio_close");
! pthread_mutex_lock(&x->x_mutex); ! x->x_requestcode = REQUEST_CLOSE; ! pthread_cond_signal(&x->x_requestcondition); ! pthread_mutex_unlock(&x->x_mutex); return (1); } --- 380,393 ---- debug_print(LOG_DEBUG,"hidio_close");
! /* just to be safe, stop it first */ ! hidio_stop_poll(x); ! ! if(! hidio_close_device(x)) ! { ! debug_print(LOG_INFO,"[hidio] closed device %d",x->x_device_number); ! x->x_device_open = 0; ! return (0); ! } ! return (1); } *************** *** 410,433 **** static void hidio_open(t_hidio *x, t_symbol *s, int argc, t_atom *argv) { - short device_number; debug_print(LOG_DEBUG,"hid_%s",s->s_name); ! pthread_mutex_lock(&x->x_mutex); ! device_number = get_device_number_from_arguments(argc, argv); ! if (device_number > -1) { ! x->x_device_number = device_number; ! x->x_requestcode = REQUEST_OPEN; ! pthread_cond_signal(&x->x_requestcondition); } else debug_print(LOG_WARNING,"[hidio] device does not exist"); ! pthread_mutex_unlock(&x->x_mutex); }
! /* read from event queue, called from child thread, no mutex needed */ ! t_int hidio_child_read(t_hidio *x) { ! // debug_print(LOG_DEBUG,"hidio_child_read"); t_hid_element *current_element; unsigned int i; --- 404,449 ---- static void hidio_open(t_hidio *x, t_symbol *s, int argc, t_atom *argv) { debug_print(LOG_DEBUG,"hid_%s",s->s_name); + short new_device_number = get_device_number_from_arguments(argc, argv); + t_int started = x->x_started; // store state to restore after device is opened ! if (new_device_number > -1) { ! /* check whether we have to close previous device */ ! if (x->x_device_open && new_device_number != x->x_device_number) ! { ! hidio_close(x); ! } ! /* no device open, so open one now */ ! if (!x->x_device_open) ! { ! if(hidio_open_device(x, new_device_number)) ! { ! x->x_device_number = -1; ! error("[hidio] can not open device %d",new_device_number); ! } ! else ! { ! x->x_device_open = 1; ! x->x_device_number = new_device_number; ! /* restore the polling state so that when I [tgl] is used to ! * start/stop [hidio], the [tgl]'s state will continue to ! * accurately reflect [hidio]'s state */ ! if (started) ! hidio_set_from_float(x,x->x_delay); // TODO is this useful? ! debug_print(LOG_DEBUG,"[hidio] set device# to %d",new_device_number); ! output_device_number(x); ! } ! } } else debug_print(LOG_WARNING,"[hidio] device does not exist"); ! /* always output open result so you can test for success in Pd space */ ! output_open_status(x); }
! static void hidio_tick(t_hidio *x) { ! // debug_print(LOG_DEBUG,"hidio_tick"); t_hid_element *current_element; unsigned int i; *************** *** 438,442 **** clock_getftime(&right_now); #endif /* PD */ ! if(right_now > last_execute_time[x->x_device_number]) { --- 454,460 ---- clock_getftime(&right_now); #endif /* PD */ ! ! debug_print(LOG_DEBUG,"# %u\tnow: %u\tlast: %u", x->x_device_number, ! right_now, last_execute_time[x->x_device_number]); if(right_now > last_execute_time[x->x_device_number]) { *************** *** 456,494 **** } } - - // TODO: why is this 1? - return 1; - } - - static void *hidio_tick(t_hidio *x) - { - pthread_mutex_lock(&x->x_mutex); - if (x->x_requestcode == REQUEST_NOTHING) - { - x->x_requestcode = REQUEST_READ; - pthread_cond_signal(&x->x_requestcondition); - } if (x->x_started) { clock_delay(x->x_clock, x->x_delay); } - pthread_mutex_unlock(&x->x_mutex); - return NULL; - } - - static void hidio_print(t_hidio *x) - { - pthread_mutex_lock(&x->x_mutex); - x->x_requestcode = REQUEST_PRINT; - pthread_cond_signal(&x->x_requestcondition); - pthread_mutex_unlock(&x->x_mutex); }
static void hidio_info(t_hidio *x) { ! pthread_mutex_lock(&x->x_mutex); ! x->x_requestcode = REQUEST_INFO; ! pthread_cond_signal(&x->x_requestcondition); ! pthread_mutex_unlock(&x->x_mutex); }
--- 474,491 ---- } } if (x->x_started) { clock_delay(x->x_clock, x->x_delay); } }
static void hidio_info(t_hidio *x) { ! output_open_status(x); ! output_device_number(x); ! output_device_count(x); ! output_poll_time(x); ! output_element_ranges(x); ! hidio_platform_specific_info(x); }
*************** *** 500,504 **** }
! #ifndef PD static void hidio_int(t_hidio* x, long l) { --- 497,501 ---- }
! #ifndef PD /* Max */ static void hidio_int(t_hidio* x, long l) { *************** *** 511,693 **** static void hidio_debug(t_hidio *x, t_float f) { - pthread_mutex_lock(&x->x_mutex); global_debug_level = f; - pthread_mutex_unlock(&x->x_mutex); - } - - - /*------------------------------------------------------------------------------ - * child thread - */ - - static void *hidio_child(void *zz) - { - t_hidio *x = zz; - short device_number = -1; - - pthread_mutex_lock(&x->x_mutex); - while (1) - { - if (x->x_requestcode == REQUEST_NOTHING) - { - pthread_cond_signal(&x->x_answercondition); - pthread_cond_wait(&x->x_requestcondition, &x->x_mutex); - } - else if (x->x_requestcode == REQUEST_OPEN) - { - short new_device_number = x->x_device_number; - /* store running state to be restored after the device has been opened */ - t_int started = x->x_started; - int ret; - /* check whether we have to close previous device */ - if (x->x_device_open && device_number != x->x_device_number) - { - pthread_mutex_unlock(&x->x_mutex); - stop_poll(x); - ret = hidio_close_device(x); - pthread_mutex_lock(&x->x_mutex); - x->x_device_open = 0; - device_number = -1; - } - /* no device open, so open one now */ - if (!x->x_device_open) - { - pthread_mutex_unlock(&x->x_mutex); - ret = hidio_open_device(x, new_device_number); - pthread_mutex_lock(&x->x_mutex); - if (ret) - { - x->x_device_number = -1; - error("[hidio] can not open device %d",device_number); - } - else - { - x->x_device_open = 1; - device_number = x->x_device_number; /* keep local copy */ - pthread_mutex_unlock(&x->x_mutex); - /* restore the polling state so that when I [tgl] is used to start/stop [hidio], - * the [tgl]'s state will continue to accurately reflect [hidio]'s state */ - if (started) - hidio_set_from_float(x,x->x_delay); - debug_print(LOG_DEBUG,"[hidio] set device# to %d",device_number); - output_open_status(x); - output_device_number(x); - pthread_mutex_lock(&x->x_mutex); - } - } - if (x->x_requestcode == REQUEST_OPEN) - x->x_requestcode = REQUEST_NOTHING; - pthread_cond_signal(&x->x_answercondition); - } - else if (x->x_requestcode == REQUEST_READ) - { - pthread_mutex_unlock(&x->x_mutex); - hidio_child_read(x); - pthread_mutex_lock(&x->x_mutex); - if (x->x_requestcode == REQUEST_READ) - x->x_requestcode = REQUEST_NOTHING; - pthread_cond_signal(&x->x_answercondition); - } - else if (x->x_requestcode == REQUEST_SEND) - { - if (x->x_requestcode == REQUEST_SEND) - x->x_requestcode = REQUEST_NOTHING; - pthread_cond_signal(&x->x_answercondition); - } - else if (x->x_requestcode == REQUEST_PRINT) - { - pthread_mutex_unlock(&x->x_mutex); - hidio_doprint(x); - pthread_mutex_lock(&x->x_mutex); - if (x->x_requestcode == REQUEST_PRINT) - x->x_requestcode = REQUEST_NOTHING; - pthread_cond_signal(&x->x_answercondition); - } - else if (x->x_requestcode == REQUEST_INFO) - { - pthread_mutex_unlock(&x->x_mutex); - output_open_status(x); - output_device_number(x); - output_device_count(x); - output_poll_time(x); - output_element_ranges(x); - hidio_platform_specific_info(x); - pthread_mutex_lock(&x->x_mutex); - if (x->x_requestcode == REQUEST_INFO) - x->x_requestcode = REQUEST_NOTHING; - pthread_cond_signal(&x->x_answercondition); - } - else if (x->x_requestcode == REQUEST_CLOSE) - { - t_int ret; - pthread_mutex_unlock(&x->x_mutex); - stop_poll(x); - ret = hidio_close_device(x); - pthread_mutex_lock(&x->x_mutex); - if (!ret) - { - debug_print(LOG_INFO,"[hidio] closed device %d",x->x_device_number); - x->x_device_open = 0; - } - if (x->x_requestcode == REQUEST_CLOSE) - x->x_requestcode = REQUEST_NOTHING; - pthread_cond_signal(&x->x_answercondition); - } - else if (x->x_requestcode == REQUEST_QUIT) - { - pthread_mutex_unlock(&x->x_mutex); - stop_poll(x); - hidio_close_device(x); - pthread_mutex_lock(&x->x_mutex); - x->x_requestcode = REQUEST_NOTHING; - pthread_cond_signal(&x->x_answercondition); - break; /* leave the while loop */ - } - else - { - ; /* nothing: shouldn't get here anyway */ - } - } - pthread_mutex_unlock(&x->x_mutex); - return (0); - } - - /* change priority of child thread */ - #ifdef PD - static void hidio_priority(t_hidio *x, t_floatarg p) - #else - static void hidio_priority(t_hidio *x, long p) - #endif - { - pthread_mutex_lock(&x->x_mutex); - p = 2 * (CLIP(p, 0, 10) - 5); - if (x->x_thread) - { - struct sched_param parm; - int policy; - if (pthread_getschedparam(x->x_thread, &policy, &parm) < 0) - { - post("hidio: warning: failed to get thread priority"); - } - else - { - parm.sched_priority = x->x_priority + (int)p; /* adjust priority */ - - if (parm.sched_priority < sched_get_priority_min(policy)) - { - parm.sched_priority = sched_get_priority_min(policy); - } - else if (parm.sched_priority > sched_get_priority_max(policy)) - { - parm.sched_priority = sched_get_priority_max(policy); - } - - if (pthread_setschedparam(x->x_thread, policy, &parm) < 0) - { - post("hidio: warning: failed to change thread priority to %d", parm.sched_priority); - } - } - } - pthread_mutex_unlock(&x->x_mutex); }
--- 508,512 ---- *************** *** 698,737 **** static void hidio_free(t_hidio* x) { - void *threadrtn; - debug_print(LOG_DEBUG,"hidio_free"); - - /* stop polling for input */ - if (x->x_clock) - clock_unset(x->x_clock); - - pthread_mutex_lock(&x->x_mutex); - /* request QUIT and wait for acknowledge */ - x->x_requestcode = REQUEST_QUIT; - if (x->x_thread) - { - post("hidio: stopping worker thread. . ."); - pthread_cond_signal(&x->x_requestcondition); - while (x->x_requestcode != REQUEST_NOTHING) - { - post("hidio: ...signalling..."); - pthread_cond_signal(&x->x_requestcondition); - pthread_cond_wait(&x->x_answercondition, &x->x_mutex); - } - pthread_mutex_unlock(&x->x_mutex); - if (pthread_join(x->x_thread, &threadrtn)) - error("hidio_free: join failed"); - post("hidio: ...done"); - } - else pthread_mutex_unlock(&x->x_mutex);
clock_free(x->x_clock); hidio_instance_count--;
hidio_platform_specific_free(x); - - pthread_cond_destroy(&x->x_requestcondition); - pthread_cond_destroy(&x->x_answercondition); - pthread_mutex_destroy(&x->x_mutex); }
--- 517,527 ---- static void hidio_free(t_hidio* x) { debug_print(LOG_DEBUG,"hidio_free");
+ hidio_close(x); clock_free(x->x_clock); hidio_instance_count--;
hidio_platform_specific_free(x); }
*************** *** 769,776 **** #endif /* _WIN32 */
- pthread_mutex_init(&x->x_mutex, 0); - pthread_cond_init(&x->x_requestcondition, 0); - pthread_cond_init(&x->x_answercondition, 0); - x->x_device_number = get_device_number_from_arguments(argc, argv);
--- 559,562 ---- *************** *** 778,784 **** hidio_instance_count++;
- x->x_requestcode = REQUEST_NOTHING; - pthread_create(&x->x_thread, 0, hidio_child, x); - return (x); } --- 564,567 ---- *************** *** 821,827 **** class_addmethod(hidio_class,(t_method) hidio_ff_print,gensym("ff_print"),0);
- class_addmethod(hidio_class,(t_method) hidio_priority, gensym("priority"), A_FLOAT, A_NULL); - - post("[hidio] %d.%d, written by Hans-Christoph Steiner hans@eds.org", HIDIO_MAJOR_VERSION, HIDIO_MINOR_VERSION); --- 604,607 ---- *************** *** 915,919 **** class_addmethod(c, (method)hidio_ff_print, "ff_print",0); /* perfomrance / system stuff */ - class_addmethod(c, (method)hidio_priority, "priority", A_LONG,0);
class_addmethod(c, (method)hidio_assist, "assist", A_CANT, 0); --- 695,698 ----
Index: hidio_darwin.c =================================================================== RCS file: /cvsroot/pure-data/externals/io/hidio/hidio_darwin.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** hidio_darwin.c 8 Dec 2006 11:28:25 -0000 1.4 --- hidio_darwin.c 31 Dec 2006 22:49:16 -0000 1.5 *************** *** 3,8 **** * Apple Darwin HID Manager support for Pd [hidio] object * - * some code from SuperCollider3's SC_HID.cpp by Jan Truetzschler Falkenstein - * * Copyright (c) 2004 Hans-Christoph All rights reserved. * --- 3,6 ---- *************** *** 48,59 **** #include <IOKit/hid/IOHIDUsageTables.h> #include <ForceFeedback/ForceFeedback.h>
#include <mach/mach.h> #include <mach/mach_error.h>
#include "hidio.h"
! #define DEBUG(x) ! //#define DEBUG(x) x
/*============================================================================== --- 46,59 ---- #include <IOKit/hid/IOHIDUsageTables.h> #include <ForceFeedback/ForceFeedback.h> + #include <CoreServices/CoreServices.h>
#include <mach/mach.h> + #include <mach/mach_time.h> #include <mach/mach_error.h>
#include "hidio.h"
! //#define DEBUG(x) ! #define DEBUG(x) x
/*============================================================================== *************** *** 61,69 **** *======================================================================== */
- extern t_int hidio_instance_count; // in hidio.h - /* store device pointers so I don't have to query them all the time */ pRecDevice device_pointer[MAX_DEVICES];
// this stuff is moving to the t_hid_element struct --- 61,72 ---- *======================================================================== */
/* store device pointers so I don't have to query them all the time */ pRecDevice device_pointer[MAX_DEVICES];
+ // temp hack for measuring latency + #define LATENCY_MAX 8192 + int latency[LATENCY_MAX]; + int latency_i; + int latency_average;
// this stuff is moving to the t_hid_element struct *************** *** 137,141 **** case kHIDUsage_GD_Wheel: convert_axis_to_symbols(pCurrentHIDElement, new_element, 8); break; case kHIDUsage_GD_Hatswitch: ! // this is still a mystery how to handle new_element->type = ps_absolute; new_element->name = absolute_symbols[9]; /* hatswitch */ --- 140,144 ---- case kHIDUsage_GD_Wheel: convert_axis_to_symbols(pCurrentHIDElement, new_element, 8); break; case kHIDUsage_GD_Hatswitch: ! // TODO: this is still a mystery how to handle, due to USB HID vs. Linux input.h new_element->type = ps_absolute; new_element->name = absolute_symbols[9]; /* hatswitch */ *************** *** 279,282 **** --- 282,304 ---- /* ============================================================================== */
+ double calculate_event_latency( uint64_t endTime, uint64_t startTime ) + { + uint64_t difference = endTime - startTime; + static double conversion = 0.0; + + if( 0.0 == conversion ) + { + mach_timebase_info_data_t info; + kern_return_t err = mach_timebase_info( &info ); + if( 0 == err ) + { + //convert to seconds (multiply by 1e-6 to get miliseconds) + conversion = 1e-6 * (double) info.numer / (double) info.denom; + } + } + return conversion * (double) difference; + } + + short get_device_number_by_id(unsigned short vendor_id, unsigned short product_id) { *************** *** 381,384 **** --- 403,411 ---- pCurrentHIDElement = HIDGetFirstDeviceElement( pCurrentHIDDevice, kHIDElementTypeInput ); + + /* TODO: axes should be the first elements in the array since they + * produce many more events than buttons. This will save loop cycles + * in the read statement, since it had to cycle thru the elements to + * find a match. */ while( pCurrentHIDElement != NULL) { *************** *** 397,427 **** element[x->x_device_number]); ! if( (pCurrentHIDElement->usagePage == kHIDPage_GenericDesktop) && ! (!pCurrentHIDElement->relative) ) { ! switch(pCurrentHIDElement->usage) { ! case kHIDUsage_GD_X: ! case kHIDUsage_GD_Y: ! case kHIDUsage_GD_Z: ! case kHIDUsage_GD_Rx: ! case kHIDUsage_GD_Ry: ! case kHIDUsage_GD_Rz: ! case kHIDUsage_GD_Slider: ! case kHIDUsage_GD_Dial: ! case kHIDUsage_GD_Wheel: ! //case kHIDUsage_GD_Hatswitch: // hatswitches are more like buttons, so queue them ! debug_print(LOG_INFO,"[hidio] storing absolute axis to poll %s, %s (0x%04x 0x%04x)", ! type_name, usage_name, pCurrentHIDElement->usagePage, pCurrentHIDElement->usage); - if(HIDDequeueElement(pCurrentHIDDevice,pCurrentHIDElement) != kIOReturnSuccess) - debug_print(LOG_ERR,"[hidio] could not dequeue element"); - new_element->polled = 1; - break; } } ! else { ! debug_print(LOG_INFO,"[hidio] queuing element %s, %s (0x%04x 0x%04x)", type_name, usage_name, pCurrentHIDElement->usagePage, pCurrentHIDElement->usage); --- 424,461 ---- element[x->x_device_number]); ! if(!pCurrentHIDElement->relative) /* relative elements should remain queued */ { ! switch( pCurrentHIDElement->usagePage) { ! case kHIDPage_GenericDesktop: ! switch(pCurrentHIDElement->usage) ! { ! case kHIDUsage_GD_X: ! case kHIDUsage_GD_Y: ! case kHIDUsage_GD_Z: ! case kHIDUsage_GD_Rx: ! case kHIDUsage_GD_Ry: ! case kHIDUsage_GD_Rz: ! case kHIDUsage_GD_Slider: ! case kHIDUsage_GD_Dial: ! case kHIDUsage_GD_Wheel: ! //case kHIDUsage_GD_Hatswitch: // hatswitches are more like buttons, so queue them ! debug_print(LOG_INFO,"[hidio] storing absolute axis to poll %s, %s (0x%04x 0x%04x)", ! type_name, usage_name, ! pCurrentHIDElement->usagePage, pCurrentHIDElement->usage); ! if(HIDDequeueElement(pCurrentHIDDevice,pCurrentHIDElement) != kIOReturnSuccess) ! debug_print(LOG_ERR,"[hidio] could not dequeue element"); ! new_element->polled = 1; ! break; ! } ! default: ! debug_print(LOG_INFO,"\tqueuing element %s, %s (0x%04x 0x%04x)", ! type_name, usage_name, pCurrentHIDElement->usagePage, pCurrentHIDElement->usage); } } ! else { ! debug_print(LOG_INFO,"\tqueuing element %s, %s (0x%04x 0x%04x)", type_name, usage_name, pCurrentHIDElement->usagePage, pCurrentHIDElement->usage); *************** *** 609,621 **** void hidio_get_events(t_hidio *x) { ! unsigned int i; ! pRecDevice pCurrentHIDDevice; ! t_hid_element *current_element; ! IOHIDEventStruct event;
pCurrentHIDDevice = device_pointer[x->x_device_number];
/* get the queued events first and store them */ ! // while( (HIDGetEvent(pCurrentHIDDevice, (void*) &event)) && (event_counter < MAX_EVENTS_PER_POLL) ) while(HIDGetEvent(pCurrentHIDDevice, (void*) &event)) { --- 643,656 ---- void hidio_get_events(t_hidio *x) { ! unsigned int i,j; ! pRecDevice pCurrentHIDDevice; ! t_hid_element *current_element; ! IOHIDEventStruct event; ! uint64_t timestamp, now, difference;
pCurrentHIDDevice = device_pointer[x->x_device_number];
/* get the queued events first and store them */ ! // TODO: while( (HIDGetEvent(pCurrentHIDDevice, (void*) &event)) && (event_counter < MAX_EVENTS_PER_POLL) ) while(HIDGetEvent(pCurrentHIDDevice, (void*) &event)) { *************** *** 629,635 **** current_element->value = event.value; ! debug_print(LOG_DEBUG,"output this: %s %s %d prev %d",current_element->type->s_name, ! current_element->name->s_name, current_element->value, ! current_element->previous_value); } /* absolute axes don't need to be queued, they can just be polled */ --- 664,696 ---- current_element->value = event.value; ! // debug_print(LOG_DEBUG,"output this: %s %s %d prev %d",current_element->type->s_name, ! // current_element->name->s_name, current_element->value, ! // current_element->previous_value); ! // debug_print(LOG_DEBUG,"timestamp: %u %u", event.timestamp.hi, event.timestamp.lo); ! timestamp = * (uint64_t *) &(event.timestamp); ! now = mach_absolute_time(); ! difference = calculate_event_latency(now, timestamp); ! // temp hack to measure latency ! if( latency_i < LATENCY_MAX) ! { ! latency[latency_i] = (int) difference; ! if( latency[latency_i] < 100 ) ! latency_average += latency[latency_i]; ! ++latency_i; ! } ! else ! { ! /* for(j=0;j<LATENCY_MAX;++j) ! { ! fprintf(stderr,"%d ",latency[j]); ! }*/ ! latency_average = latency_average / LATENCY_MAX; ! fprintf(stderr,"average: %d\n",latency_average); ! latency_i = 0; ! latency_average = 0; ! } ! // debug_print(LOG_DEBUG,"\t\t\t\t\ttimestamp: %llu",timestamp); ! // debug_print(LOG_DEBUG,"\t\t\t\t\tdifference: %llu", difference); ! // post("%d %llu", i, difference); } /* absolute axes don't need to be queued, they can just be polled */ *************** *** 646,650 **** }
! t_int hidio_open_device(t_hidio *x, short device_number) { --- 707,711 ---- }
! // TODO: return the same as POSIX open()/close() - 0=success, -1=fail t_int hidio_open_device(t_hidio *x, short device_number) { *************** *** 657,660 **** --- 718,723 ---- FFDeviceObjectReference ffDeviceReference = NULL;
+ latency_i = 0;latency_average = 0; // temp hack, to be removed + /* rebuild device list to make sure the list is current */ if( !HIDHaveDeviceList() ) hidio_build_device_list(); *************** *** 695,699 **** }
! t_int hidio_close_device(t_hidio *x) { --- 758,762 ---- }
! // TODO: return the same as POSIX open()/close() - 0=success, -1=fail t_int hidio_close_device(t_hidio *x) { *************** *** 739,743 ****
/* TODO: this should be dumped for [devices( and [elements( messages */ ! void hidio_doprint(t_hidio *x) { if( !HIDHaveDeviceList() ) hidio_build_device_list(); --- 802,806 ----
/* TODO: this should be dumped for [devices( and [elements( messages */ ! void hidio_print(t_hidio *x) { if( !HIDHaveDeviceList() ) hidio_build_device_list(); *************** *** 753,756 **** --- 816,820 ---- void hidio_platform_specific_free(t_hidio *x) { + int j; debug_print(LOG_DEBUG,"hidio_platform_specific_free"); /* only call this if the last instance is being freed */ *************** *** 761,764 **** --- 825,832 ---- HIDReleaseDeviceList(); } + for(j=0;j<LATENCY_MAX;++j) + { + fprintf(stderr,"%d ",latency[j]); + } }
Index: Makefile =================================================================== RCS file: /cvsroot/pure-data/externals/io/hidio/Makefile,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Makefile 8 Dec 2006 06:33:26 -0000 1.2 --- Makefile 31 Dec 2006 22:49:16 -0000 1.3 *************** *** 16,20 **** # for emacs etags: ! etags ../../../pd/src/*.h *.[ch] linux/input.h make etags_`uname -s`
--- 16,21 ---- # for emacs etags: ! etags ../../../pd/src/*.h *.[ch] linux/input.h /usr/include/stdlib.h \ ! /usr/include/time.h /usr/include/stdio.h make etags_`uname -s`
*************** *** 23,27 **** /System/Library/Frameworks/ForceFeedback.framework/Headers/*.h \ /System/Library/Frameworks/Carbon.framework/Headers/*.h \ ! /System/Library/Frameworks/IOKit.framework/Headers/hid*/*.[ch]
etags_Linux: --- 24,31 ---- /System/Library/Frameworks/ForceFeedback.framework/Headers/*.h \ /System/Library/Frameworks/Carbon.framework/Headers/*.h \ ! /System/Library/Frameworks/CoreServices.framework/Headers/*.h \ ! /System/Library/Frameworks/IOKit.framework/Headers/*.[ch] \ ! /System/Library/Frameworks/IOKit.framework/Headers/hid*/*.[ch] \ ! /usr/include/mach/*.h
etags_Linux:
Index: hidio_linux.c =================================================================== RCS file: /cvsroot/pure-data/externals/io/hidio/hidio_linux.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** hidio_linux.c 8 Dec 2006 06:33:26 -0000 1.2 --- hidio_linux.c 31 Dec 2006 22:49:16 -0000 1.3 *************** *** 435,439 **** }
! t_int hidio_open_device(t_hidio *x, short device_number) { --- 435,439 ---- }
! // TODO: return the same as POSIX open()/close() - 0=success, -1=fail t_int hidio_open_device(t_hidio *x, short device_number) { *************** *** 478,484 **** }
! /* ! * Under GNU/Linux, the device is a filehandle ! */ t_int hidio_close_device(t_hidio *x) { --- 478,483 ---- }
! /* Under GNU/Linux, the device is a filehandle */ ! // TODO: return the same as POSIX open()/close() - 0=success, -1=fail t_int hidio_close_device(t_hidio *x) {
Index: hidio-help.pd =================================================================== RCS file: /cvsroot/pure-data/externals/io/hidio/hidio-help.pd,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** hidio-help.pd 8 Dec 2006 06:33:26 -0000 1.3 --- hidio-help.pd 31 Dec 2006 22:49:16 -0000 1.4 *************** *** 1,3 **** ! #N canvas 157 38 862 587 10; #X floatatom 27 445 5 0 0 0 - - -; #X floatatom 83 445 5 0 0 0 - - -; --- 1,3 ---- ! #N canvas 157 38 878 603 10; #X floatatom 27 445 5 0 0 0 - - -; #X floatatom 83 445 5 0 0 0 - - -; *************** *** 271,275 **** #X obj 459 508 tgl 25 0 empty empty empty 0 -6 0 8 -195568 -1 -1 0 1; ! #X msg 25 155 debug 0; #X msg 298 145 info; #N canvas 743 25 411 235 see 0; --- 271,275 ---- #X obj 459 508 tgl 25 0 empty empty empty 0 -6 0 8 -195568 -1 -1 0 1; ! #X msg 25 155 debug 9; #X msg 298 145 info; #N canvas 743 25 411 235 see 0; *************** *** 399,406 **** ; #N canvas 162 133 570 420 serin 0; ! #X obj 209 61 cnv 15 15 15 empty $0-debug-canvas 0 4 8 0 14 -233017 -1 0; #X obj 60 61 hradio 15 1 1 10 empty empty empty 0 -6 0 8 -261689 -1 ! -1 0; #X obj 60 13 inlet; #X msg 200 202 label $1; --- 399,406 ---- ; #N canvas 162 133 570 420 serin 0; ! #X obj 209 61 cnv 15 15 15 empty $0-debug-canvas 9 4 8 0 14 -233017 -1 0; #X obj 60 61 hradio 15 1 1 10 empty empty empty 0 -6 0 8 -261689 -1 ! -1 9; #X obj 60 13 inlet; #X msg 200 202 label $1; *************** *** 479,483 **** #X obj 9 466 route a_key b_key c_key d_key e_key f_key g_key h_key i_key j_key k_key l_key m_key n_key o_key p_key; ! #N canvas 114 93 471 350 raw 0; #X obj 144 45 inlet; #X obj 88 104 route DESKTOP; --- 479,483 ---- #X obj 9 466 route a_key b_key c_key d_key e_key f_key g_key h_key i_key j_key k_key l_key m_key n_key o_key p_key; ! #N canvas 114 93 475 354 raw 0; #X obj 144 45 inlet; #X obj 88 104 route DESKTOP; *************** *** 494,497 **** --- 494,498 ---- #X obj 333 99 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; + #X obj 354 45 inlet; #X connect 0 0 1 0; #X connect 0 0 8 0; *************** *** 504,509 **** --- 505,513 ---- #X connect 8 0 9 0; #X connect 10 0 8 1; + #X connect 11 0 10 0; #X restore 408 294 pd raw; #X floatatom 63 401 6 0 0 0 - - -; + #X obj 455 295 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 + 1; #X connect 2 0 65 0; #X connect 8 0 65 0; *************** *** 561,562 **** --- 565,567 ---- #X connect 74 14 51 0; #X connect 74 15 52 0; + #X connect 77 0 75 1;
Index: TODO =================================================================== RCS file: /cvsroot/pure-data/externals/io/hidio/TODO,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TODO 30 Nov 2006 05:53:40 -0000 1.1 --- TODO 31 Dec 2006 22:49:16 -0000 1.2 *************** *** 53,60 **** = make only the first executed instance fetch the data
! the function is ugen_getsortno() -- returns ! an integer which increases eachtime DSP is restarted. You can add the ! function call (to the ugen chain for instance) each time you see ! ugen_getsortno() return an integer greater than the previous one you've
______________________________________________________________________________ --- 53,62 ---- = make only the first executed instance fetch the data
! - double right_now = clock_getlogicaltime(); ! this only works when instances are in the same patch, not when instances are ! in different patches ! ! - implement event output data structure !
______________________________________________________________________________