Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / HelpSource / Classes / GeneralHID.schelp
blobba00a9a58905936d16a228d0039bf8d7d58a53aa
1 class:: GeneralHID
2 redirect:: implClass
3 summary:: A uniform class to access HID devices
4 related:: Classes/HIDDeviceService, Classes/LID, Classes/GeneralHIDDevice, Classes/GeneralHIDSpec
5 categories:: External Control>HID
7 description::
8 GeneralHID is a cross platform wrapper for accessing HID devices. Currently the MacOSX and Linux HID support has been wrapped. Some of the code is inspired by the GUI wrapper.
10 note::
11 It is advised to use this class instead of the platform specific classes: link::Classes/HIDDeviceService:: (on MacOSX) and link::Classes/LID:: (on Linux).
14 There are intermediate "bridge" classes link::Classes/MXHID:: (on MacOSX) and link::Classes/GLID:: (on Linux), which should not be used directly, but their names will show up in the output of some of the methods of GeneralHID.
16 subsection::Some outstanding issues
17 This class is not completely finished yet. Common slot numbers across platforms are not yet guaranteed. On Windows there is not yet a proper implementation available, but you can use HID Server from http://ixi-software.net/content/backyard.html , which comes with classes which are compatible with GeneralHID.
19 subsection::Further information
20 See link::Classes/GeneralHIDDevice:: for a documentation of the methods to access an HID device.
21 See link::Classes/GeneralHIDSpec:: for a documentation of how to access slots by name, instead of numbers.
23 ClassMethods::
25 private::initClass
27 method::scheme, current
28 Get the current scheme. With scheme.id and current.id one can get the current scheme ID.
30 method::buildDeviceList
31 Look for all connected devices and build a device list. This returns the devicelist as an link::Classes/Array::.
33 method::deviceList
34 Returns the device list if it has already been built before.
36 method::postDevices
37 Posts a readable list of devices.
39 method::postDevicesAndProperties
40 Posts a readable list of devices and their properties.
42 method::startEventLoop
43 Start the eventloop with a update rate (or rather update time in seconds).
45 note::
46 this is only really needed on MacOSX, but for crossplatform code you should include it in your code.
49 method::stopEventLoop
50 Stop the eventloop.
52 method::eventLoopIsRunning
53 Check status of eventloop.
55 method::open
56 Opens the device; the device should be an item got from the device list.
58 method::findBy
59 Find a device by its info properties.
61 argument::vendorID
62 manufacturer
64 argument::productID
65 product identifier as given by manufacturer
67 argument::locID
68 identifier for the physical connection to your computer
70 argument::versionID
71 a version of the product, as given by the manufacturer
73 Examples::
75 code::
76 // General structure to access a device
77 // Look for the devices that are attached:
78 GeneralHID.buildDeviceList;
79 // Get the list of devices:
80 d = GeneralHID.deviceList;
81 // Check which devices have been found:
82 GeneralHID.postDevices;
83 // Pick the 6th device and open it and create an instance of it:
84 a = GeneralHID.open( d[5] )
85 // Get info on the device:
86 a.info;
87 // if you want to automatically find the device when you restart you can use the GeneralHID.findBy method. To get the arguments you should use for this function, you can use:
88 a.info.findArgs;
89 // this outputs for my Impact gamepad:
90 [ 1973, 786, usb-0000:00:1d.0-1/input0, 272 ]
91 // close the device, as we will reopen it in the next lines
92 a.close;
93 // if we know which device we want, we can find it:
94 b = GeneralHID.findBy( 1973, 786, "usb-0000:00:1d.0-1/input0", 272 );
95 // if you do not care about the version or the location, you can also do:
96 b = GeneralHID.findBy( 1973, 786 );
97 // or if you do not even care about the productID
98 b = GeneralHID.findBy( 1973 );
99 // you can then open it by:
100 a = GeneralHID.open( b )
101 // Start eventloop:
102 GeneralHID.startEventLoop
103 // Get the capabilities of the device in a readable format:
104 a.caps;
105 // there are different types of slots:
106 // button (type 1), has only on/off (1/0) states
107 // relative (type 2), counts up or down (scrollwheel for example)
108 // absolute (type 3), continuous value between 0 and 1
109 // some other may show up on Linux ( Syn (type 0) and Miscellaneous (type 4), but these are generally not very useful).
110 // See if data is coming in:
111 a.debug_( true );
112 // Stop it:
113 a.debug_( false );
114 // Debugging can be turned on for each slot individually, if necessary:
115 //(IBM trackpoint)
116 a.slots[1].at( 272 ).debug_( true );
117 // (external mouse on macbook pro)
118 a.slots[3][1].debug_(true);
119 (external mouse on ibm thinkpad)
120 a.slots[2][1].debug_(true);
121 // Turn it off again: // (IBM trackpoint)
122 a.slots[1].at( 272 ).debug_( false );
123 //(external mouse on macbook pro)
124 a.slots[3][48].debug_(false);
125 //(external mouse on ibm thinkpad)
126 a.slots[3][1].debug_(false);
128 // You can also create a generic gui to see what is coming in:
129 a.makeGui;
131 // The current value of a slot can be checked:
132 a.slots[1].at( 272 ).value;
133 a.slots[2].at( 1 ).value;
134 a.slots[3][1].value
135 //If the slot is an LED, you can set the value:
136 a.slots[11][0].value = 1;
137 a.slots[11][0].value = 0;
139 // Actions can be mapped to each slot individually.
140 a.slots[1].at( 272 ).action_( { "hello".postln; } );
141 a.slots[1].at( 273 ).action_( { "hi".postln; } );
142 a.slots[3].at( 1 ).action_( { "hi".postln; } );
143 // with an input to the function
144 a.slots[3].at( 1 ).action_( { |v| "hi, my value is ".post; v.value.postln; } );
145 a.slots[1].at( 272 ).action_( { |v| "hi, my value is ".post; v.value.postln; } );
147 // To stop the action, assign it to an empty function.
148 a.slots[1].at( 272 ).action_( {} );
149 a.slots[1].at( 273 ).action_( {} );
150 a.slots[3].at( 1 ).action_( {} );
152 // you can access slots, by giving them a key:
153 a.add( \lx, [3,0] );
154 a[\lx].debug_( true );
155 // the last item in the output array, now shows the key
156 a[\lx].debug_( false );
157 // save the spec for future use:
158 a.spec.save( "Impact_help" );
159 // find a spec defined previously for this device:
160 c = a.findSpec;
161 // set it:
162 a.setSpec( c[0] );
163 // more info on this in the [GeneralHIDSpec] helpfile
164 // If the server is running you can create a control bus for the HID data to go to, so that a synth can immediately read the data:
165 s = Server.local.boot;
166 // To create the bus:
167 a.slots[1].at( 272 ).createBus( s ); a.slots[2].at( 8 ).createBus( s );
169 SynthDef( \hidbus_help, { |out=0,amp=0|
170         Out.ar( out, SinOsc.ar( 300, 0, 0.01*amp.abs ) );
171 }).add;
173 x = Synth.new( \hidbus_help );
174 x.map( \amp, a.slots[2].at( 8 ).bus );
175 x.free;
177 ( // a nicer version:
178 SynthDef( \hidbus_help, { |out=0,amp=0,amp2=0|
179         Out.ar( out, SinOsc.ar( 300, 0, 0.01*amp.abs.lag( 0.1 ) * amp2.lag(0.01,0.99) ) );
180 }).add;
182 x = Synth.new( \hidbus_help );
183 x.map( \amp, a.slots[2].at( 8 ).bus );
184 x.map( \amp2, a.slots[1].at( 272 ).bus );
185 x.free;
187 ( // an even nicer version:
188 SynthDef( \hidbus_help, { |out=0,freqadd=0,amp=0|
189         Out.ar( out, SinOsc.ar( 300 + (freqadd.lag(0.2,1)*40), 0, 0.2*amp.lag(0.01,0.99) ) );
190 }).add;
192 x = Synth.new( \hidbus_help );
193 x.map( \freqadd, a.slots[2].at( 8 ).bus );
194 x.map( \amp, a.slots[1].at( 272 ).bus );
195 x.free;
197 // To free the bus:
198 a.slots[1].at( 272 ).freeBus;
199 a.slots[2].at( 8 ).freeBus;
200 // Close the device after use:
201 a.close;
202 GeneralHID.stopEventLoop