‹ redKontroll2-devmicro_noise_joy ›

RedInfo UGens

2009-03-06 13:46:59 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.

‹ redKontroll2-devmicro_noise_joy ›