redinfo ugens

last night i wrote 3 simple ugens for supercollider. they read the sudden motion sensor, ambient light sensors and the battery capacity on portable macs. download from this page. (mac os 10.5 and later).

RedInfoSms from redFrik on Vimeo.

ideas:
RedInfoBat - read the battery's current capacity (perhaps use it as master tuning instead of 440? laptops are also instruments :-)
RedInfoLmu - read data from the left and right side ambient light sensors (low-pass filter master effect to match 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.

//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 accidently drop your computer while using these.