RedInfo UGens
2009-03-06 13:46
supercollider
Last night I wrote three simple UGens for SuperCollider. They read the sudden motion sensor, ambient light sensors and the battery capacity on portable mac laptops. Download from the page: /code/sc/#plugins. (macOS 10.5 and later).
Ideas:
RedInfoBat
- read the battery's current capacity (perhaps use it as reference tuning instead of 440? Laptops are also instruments :-)RedInfoLmu
- read data from the left or right side ambient light sensors (low-pass filter global effect to match the venue's mood-light :-)RedInfoSms
- read data from the Apple sudden motion sensor (very sensitive 3D accelerometer. Tap-tempo analysis while typing on the keyboard :-)
Below is the code for the example in the video. It is basically a remake of Cyrille Henry's classic bouncing balls (drpichon.free.fr/ch/data/msd_ch_20060603.mp4) using my redUniverse quark.
Note: new Apple laptops with SSD do not use sudden motion sensor (the hard drive no longer have any moving parts). So this example will only work with older laptops from ~2010. (battery and light sensor UGens still work though.)
//redFrik 090306, minor update 110804
(
s.waitForBoot{
var width= 1000, height= 600, w, world, n= 30;
var back= Window.new("", Window.screenBounds, false, false);
back.view.background= Color.red(0.5, 1);
back.front;
//--synthesis
SynthDef(\suddenmotionsynth, {|out= 0, freq= 400, maxDur= 0.3, amp= 1, pan= 0|
var e, z, freqs, amps, rings;
freqs= Array.geom(4, freq, Rand(1.5, 2.5));
amps= Array.geom(4, 0.5, Rand(0, 1));
rings= Array.geom(4, maxDur, Rand(0, 1))*maxDur;
e= EnvGen.ar(Env.perc(0.0025, maxDur), 1, amp, doneAction:2);
z= Klank.ar(`[freqs, amps, rings], WhiteNoise.ar(e));
Out.ar(out, Pan2.ar(z*e, pan));
}).send(s);
SynthDef(\suddenmotionsensor, {|rate= 50|
var trig= Impulse.kr(rate);
SendReply.kr(trig, 'xyz', RedInfoSms.kr(trig));
}).play(s);
//--world
w= RedWindow("RedInfo", Rect.aboutPoint(Window.screenBounds.center, width/2, height/2)).front;
world= RedWorld3(RedVector2D[width, height], RedVector2D[0, 0.98], 25, 0.25);
//--objects
{
var loc= RedVector2D[width, height].rand;
var mass= 0.5.rrand(2);
RedObject(world, loc, 0, 0, mass, mass*10); //world,loc,vel,acc,mass,size
}.dup(n);
//--responder
OSCresponder(s.addr, 'xyz', {|t, r, m|
//world.gravity= RedVector2D[m[3].neg*3, m[5]*5-4]; //some older macbooks have x inverted
world.gravity= RedVector2D[m[3]*3, m[5]*5-4];
}).add;
//--loop
w.draw{
Pen.fillColor= Color.red(1.2, 0.6);
world.objects.do{|o|
var osize, freq, amp, pan;
o.addForce(world.gravity);
o.update;
if(world.contains(o).not, {
osize= o.mass.linexp(0.5, 2, 0.15, 1);
freq= osize.linexp(0.1, 1, 600, 400);
amp= o.vel.mag.linexp(0, 25, 0.01, osize);
pan= o.loc[0]/width*2-1;
if(amp>0.02, {
Synth(\suddenmotionsynth, [\freq, freq, \maxDur, osize, \amp, amp, \pan, pan]);
});
});
world.contain(o);
//--render
Pen.fillOval(Rect.aboutRedObject2D(o));
};
}.play;
CmdPeriod.doOnce({
if(w.isClosed.not, {w.close});
if(back.isClosed.not, {back.close})
});
})
Disclaimer:
No, I'm not responsible if you accidentally drop your computer while using these.