On May 16, 2006, at 5:52 PM, Christian Klippel wrote:
hi,
Am Montag, 15. Mai 2006 13:42 schrieb Hans-Christoph Steiner:
This sounds like you are wrtiing a [libusb] object, which would be very nice.
not directly a general libusb object, altough some of the stuff may be reused for that...
I have a different suggestion, related to the question I just posted. What about not using a thread at all, and instead having the first instance executed get the data from the USB bus, and stick it in an array. Then every other instance set to read the same device will just output the data from that array. This relies on the OS doing some buffering, which in the case of HID, GNU/Linux, Mac OS X, and Windows already do.
well, first, there is more on usb than just hid.
Indeed, but I only really know about HID. I can only guess about the rest. But I would like to know if the OS generally buffers USB data. If the OS doesn't, I'll bet the hardware does somewhere.
second, what about latency? if you dont use a thread, you can only poll the device at a defined intervall. if the "master" object is the last in the chain to be scheduled, the "slaves" can update on the next slice only, adding a lag of one "tick". next, how to syncronize? i see the same problems as with using a single thread
I posted a question about finding the first instance to execute, (it seems pretty easy to do it Pd space), with the idea that the first one always does the data getting. That solves that problem. As for latency, there would be no difference in latency if a Pd object was polling a thread or polling a file in /dev/; that object would still be polling at the same rate. Adding a thread would just put extra code between the Pd object and the /dev/ file.
an a single/multiple listener(s). what about the following:
the object has a "static char slave" which is 0 on the first instance, and 1 for each other. the object itself has a thread that constantly polls the usb bus. the master calls a "processsPacket(char *data)" function when data arrives, issuing a lock before the call and unlock after it. (note that the lock only happens when new data arrives....) or a similar thing, of course. if an instance detects that it is a slave, it just doesnt start the thread, but instead registers itself to a small "list of listeners" within the master. the master then calls the processPacket() function for each registered listener. of course, slaves have to unregister upon deletion. also, if the master gets deleted, it should set the first slave in that list as the new master.
what do you think about that?
You add a lot of complexity and more running code for no real gain. If you change the data in the middle of a poll interval, I think you'll be asking for trouble. The problem here is that I want multiple instances of an object to be able to output data from the same device. The data coming out of each instance should be exactly the same, or the chance of strange, hard to find bugs will be high. If a thread updates the data in between the poll intervals, then different instances will output different data in each cycle.
Polling latency is not an issue except in rare, customized situations. The fastest that Windows and Mac OS X can output HID data is once every 10 ms. The linux kernel can do once per 1ms if you customize things, but its generally 10ms also. These times probably all apply to generic USB event data too.
Plus Pd has a built-in scheduler, and we are writing Pd objects, so we should use the Pd scheduler, instead of an external one (i.e. threads). The more threads we add to Pd, the more we take CPU time completely away from the Pd scheduler. A couple of threads probably won't matter, but if we start using a lot of threads, it will matter.
on a related matter: somehow libusb seems to be unstable/buggy on windows. i have some code here, using bulk read's and write's, that works just fine on linux, but is almost non-working on windows. the data drips in maybe one packet each second or two, with only -116 error inbetween. also, the formerly working stuff for the multio starts to make these problems on windows now. and that even without any changes to the firmware or the pd-object...
so we should definitely investigate that issue first.... do you have a pic programmer and a usb pic at hand? if so, contact me off-list so we can setup a little test-bench for that purpose ....
Yeah, I expect libusb to be troublesome on Windows. I don't really have time to troubleshoot Windows now though. I only work on Windows as a matter of necessity. Plus the HID/input device stuff on Windows is such a pain in the ass, I don't think that instrument building will ever work very well on Windows.
oh, and a last thing: how do you intend to handle hid devices when they are claimed by some other driver already? there are syscalls at least in linux to detach devices from a driver by an external task. but imagine if, by accident, someone does that with the systems mouse & keyboard?
I think this is outside the scope of this Pd object, at least for now. The object should open the devices O_NONBLOCK whenever possible and rely on other software also opening using O_NONBLOCK too. So far so good...
.hc
.hc
greets,
chris
On Tue, 2 May 2006, Christian Klippel wrote:
hi all,
can anyone confirm that using outlet_anything() inside a thread is safe? just wrote a little object that reads a usb device in a thread, and send to the outlets from there directly via outlet_anything() .... so far it doesnt crash or anything, it just works (of course there are some objects connected to them), altough its only a few route's and slider/bangs/toggles connected.
since the thing does peak detection, there is a hell lot of toggles comming in, plus some faders ... so its really quite some traffic ....
but i want to make sure that i can do it that way, and not that there are any surprises later when doing that ...
thanks,
chris
PD-dev mailing list PD-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
zen \ \ \[D[D[D[D
PD-dev mailing list PD-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
________________________________________________________________________ ____
There is no way to peace, peace is the way. -A.J. Muste