.cc - week ten.
I've had some fun using the HIDDeviceService class in SuperCollider, which allows you to use USB devices like joysticks, mice and any other devices you have lying around your studio to input data into SuperCollider. Originally I programmed a patch to run with a 5-button Microsoft mouse, but the patch presented here is designed for a Apple/Logitech single button mouse.
// HUMAN INTERFACE DEVICE (HID)
// Initialise HID
(
// Searches all HID interface pages
HIDDeviceService.buildDeviceList(
usagePage: nil,
usage: nil
);
// Establish HID List
// Output Device Data
HIDDeviceService.devices.do({
// Args
arg dev, devIdx;
// Print out device information
["DEVICE:", devIdx, dev.manufacturer, dev.product, dev.usage, dev.vendorID, dev.productID, dev.locID].postln;
});
// Establish HID and element list
// Output Device Data
HIDDeviceService.devices.do({
// Args
arg dev, devIdx;
// Print out device information
["DEVICE:", devIdx, dev, dev.manufacturer, dev.product, dev.vendorID, dev.productID, dev.locID].postln;
// Loop and output elements
dev.elements.do({
// Args
arg ele;
// Output element information
["ELEMENT:", ele.type, ele.usage, ele.cookie, ele.min, ele.max].postln;
});
"------------------------------------------------".postln;
});
// Queue device for usage
// Queue Device
HIDDeviceService.devices.at(1).queueDevice; //apple mouse
// Establish HID List and query device for usage based upon Vendor and Product ID
// Device Information
~vendorID = 1452; //apple's vendor ID
~productID = 775; //apple's product ID
// Output Device Data
HIDDeviceService.devices.do({
// Args
arg dev, devIdx;
// Print out device information
if((dev.vendorID == ~vendorID) && (dev.productID == ~productID), {
HIDDeviceService.devices.at(devIdx).queueDevice;
["CONNECTED:", devIdx, dev.manufacturer, dev.product, dev.vendorID, dev.productID, dev.locID].postln;
});
});
// Attach action to a device
// Action for Device
HIDDeviceService.action_({
// Args
arg productID, vendorID, locID, cookie, val;
// Output
[productID, vendorID, locID, cookie, val].postln;
});
)
// Start / stop event loop (for device polling)
HIDDeviceService.runEventLoop; // 20 milliseconds
HIDDeviceService.stopEventLoop;
// BUFFer
(
var path = ((PathName.new(Document.current.path)).pathOnly) ++"sample/";
v = Buffer.alloc(s,2048,2);
b = Buffer.read(
server: s,
path: path++"macstartup.wav");
// SynthDef
//may need to run this code twice, although once should be fine.
SynthDef("skyBurn", { arg out=0, bufnum=0, trigRate = 0.5, wipeBins = 0.95;
var in, chain;
in = BrownNoise.ar(0.8); //try PinkNoise, WhiteNoise, BrownNoise, GrayNoise
chain = FFT(bufnum, in);
chain = PV_RandComb(chain, wipeBins, Impulse.kr(trigRate));
Out.ar(out, IFFT(chain).dup);
}).load(s);
)
// Create Instance
~randComb = Synth("skyBurn", [\out, 0, \bufnum, v]);
// Setup Action for skyBurn
(
var w, b, line, titleBox; //GUI
~paraOne;
~paraTwo;
~sliderOne;
~sliderTwo;
// Action for Device
HIDDeviceService.action_({
// Args
arg productID, vendorID, locID, cookie, val;
// Switch Parameter
~paraOne = switch (cookie)
{3} { rrand(95, 100) * 0.01 } //get a new value
{4} { rrand(0.0, 2.0) - 1.0 * 0.01 + ~paraOne } //mouse movement
{5} { rrand(0.0, 2.0) - 1.0 * 0.01 + ~paraOne }; //mouse movement
if((cookie == 3) && (val == 0), {
~paraTwo = rrand(1, 20) * 0.01; //{rrand(1, 100) * 0.01};
{~sliderTwo.valueAction_(~paraTwo)}.defer;
});
// Print feedback
["Button", cookie, "Value", val, "Para One", ~paraOne, "Para Two", ~paraTwo].postln; //feedback
// Input control information into GUI
{~sliderOne.valueAction_(~paraOne)}.defer;
{~sliderTwo.valueAction_(~paraTwo)}.defer;
});
//GUI
w = GUI.window.new( "Fonzeey", Rect( 128, 600, 408, 316 ));
w.view.decorator = FlowLayout( w.view.bounds );
w.view.background = Color( 0.0,0.714,0.96 );
//title
titleBox = SCStaticText(
parent: w,
bounds: Rect(20, 100, 410, 65)
);
titleBox.stringColor_(Color.white);
titleBox.background_(Color(0.0,0.714,0.96));
titleBox.string_("Phase Vocoder - Random Bin Comb");
titleBox.font_(Font("Arial Black", 25));
//heading one
titleBox = SCStaticText(
parent: w,
bounds: Rect(20, 100, 410, 65)
);
titleBox.stringColor_(Color.white);
titleBox.background_(Color(0.0,0.714,0.96));
titleBox.string_("Morph between Noise and Sample");
titleBox.font_(Font("Arial Black", 15));
//slider one
~sliderOne = SCSlider(w, Rect(20, 80, 400, 40));
~sliderOne.focusColor_(Color.white);
~sliderOne.action_({ // Input control information into Synth
~randComb.set(\wipeBins, [0.01, 0.99].asSpec.map(~sliderOne.value));
});
w.front;
//heading two
titleBox = SCStaticText(
parent: w,
bounds: Rect(20, 100, 410, 65)
);
titleBox.stringColor_(Color.white);
titleBox.background_(Color(0.0,0.714,0.96));
titleBox.string_("Trigger Rate for Random Ordering:");
titleBox.font_(Font("Arial Black", 15));
//slider two
~sliderTwo = SCSlider(w, Rect(20, 80, 400, 40));
~sliderTwo.focusColor_(Color.white);
~sliderTwo.action_({ // Input control information into Synth
~randComb.set(\trigRate, [0.1, 10.1].asSpec.map(~sliderTwo.value).round(0.1));
});
w.front;
)
HID.rtf (12 kB) | exampleHID.mp3 (1.2 mB)
.sources.
Haines, Christian 23.10.08, "Human Interface Device," Lecture of EMU, Adelaide University.
iieiwrmeieweeiimeemmwreiweremweireeemeimwieewwrwweereireeiimeewmiwwwemwiewimeeeremeiewmemweewieewerwemwiimiewmeiwireiiwrrewmwewree |
28.10.08
Human Interface Devices (HID) in SuperCollider
copywrite 12:30 pm
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment