«controlling a synth with HID» by beatboxchad
on 13 Jul'23 19:33 inThere are some hardcoded values you'll have to mess with to play with this. On my Thinkpad touchscreen, an element with usage type Finger indicates a touch with a float either 1.0 or 0.0. First touch element has ID 2, followed by 13, 24, 35, 46.
The X and Y axis data ID's are similarly catchy. The X's have ID's 11, 22, 33, 44, 55 and the Y's have ID's 12, 23, 34, 45, 56.
I am using a ProxySpace stored in variable p
, and this code gets executed when sclang boots up. It's placed in that magic directory.
I also have to run sudo chmod 664 /dev/hidraw*; sudo chgrp audio /dev/hidraw*
every time I reboot, and a couple other FIXME's. I'll never get around to them, because this thing is so fun to play with. Super fun delay swooshes. I'm calling it a "Touchscreen Theramin".
This code, the name "Touchscreen Theramin", and all related content are Copyright 2023 Chad Cassady AKA beatboxchad, working from New Orleans, LA, USA. I wrote it, I'm gonna make more cool stuff out of it, don't steal the name or any of that or I'll get all mad and ask you for a share of whatever you make so we can get back to being playful. This here submission is proof of all that. Holler at me if you make something out of it, I'm down to collaborate and share.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
[2, 13, 24, 35, 46].collect({ |touch, idx| var finger = (\thinkfinger ++ (idx+1).asSymbol); var fx = finger ++ \x; var fy = finger ++ \y; var ind_x = ((idx+1) * 10) + idx+1; var ind_y = ind_x + 1; p.at(finger.asSymbol).kr; p.at(fx.asSymbol).kr; p.at(fy.asSymbol).kr; HIDdef.element(finger.asSymbol, {|val| p[finger.asSymbol].bus.set(val); val; }, touch.postln;); HIDdef.element(fx.asSymbol, {|val| p[fx.asSymbol].bus.set(val)}, ind_x.postln;); HIDdef.element(fy.asSymbol, {|val| p[fy.asSymbol].bus.set(val)}, ind_y.postln); }); p.use({ ~resonator = { arg input; var sig; sig = LocalIn.ar(2) + input; sig = DelayN.ar(sig, 3.5, \resonator.asSpec.map(\delay.kr(0.5, 0.1)) - ControlRate.ir.reciprocal); LocalOut.ar(sig * \dfeedback.kr(0.5, 0.01)); Limiter.ar(LeakDC.ar(sig)) + input; }; ~tone = { var vibrato = SinOsc.kr(\vibfreq.kr(5), mul: \vibdepth.kr(5)); Limiter.ar( LeakDC.ar( Mix([ SawDPW.ar( (\midfreq.asSpec.map(\freq.kr) + vibrato)), SinOsc.ar( (\midfreq.asSpec.map(\freq.kr) + vibrato)), ], [1, 0.5])) * \amp.asSpec.map(\amp.kr) * \play.tr(0) )!2 }; ~tone[10] = \filter -> ~resonator; ~tone.set(\freq, ~thinkfinger2x); ~tone.set(\amp, ~thinkfinger2y); ~tone.set(\play, ~thinkfinger2); ~tone.set(\wet10, 1); ~tone.set(\delay, ~thinkfinger1x); ~tone.set(\dfeedback, ~thinkfinger1y); ~tone.play; });