1. Piezo + SuperCollider

    Karst: Piezo-May-22 by Meghatron

    Using piezo sensor input to control playback of my voice.  I now have flex, force and piezo sensor input functional with my SuperCollider code.  Now comes fine-tuning these inputs, determining logical and compositionally beneficial structures.

  2. SC+ Arduino: 3 flex sensors

    //Prototype code for the composition KARST, transitioning from a score to a trigger based performance interface
    //this example uses a default SC sample: a11wlk01.wav

    //SERVER
    (
    Server.default = s = Server.internal.boot;
    s.waitForBoot({
    s.scope;
    FreqScope.new(400, 200, 0);
    });
    )

    //SERIAL
    (
    SerialPort.listDevices;
    d = SerialPort.devices[2];
    f = SCPyduino.new(d);  //declares f an SCPyduino object
    )

    (
    //VARIABLES + SCORE
    var score;
    //synths
    var synth;
    //samples
    var voice;
    //function
    var func;

    var syn1, syn2, syn3, syn4, syn5, syn6;

    //score
    score = CtkScore.new;

    //SAMPLE
    voice = CtkBuffer.playbuf(“sounds/a11wlk01.wav”).load;
    score.add(voice);

    //SYNTHDEF
    // trigger synth
    synth = CtkSynthDef(\help_PlayBuf, {arg imp, begin, out = 0, bufnum = 0, pan = 0, amp =0.5, deviation = 0;
        var trig, sig, sampstosecs, devAmt, outsig;
        trig = Impulse.ar(imp);
        sampstosecs = (SampleRate.ir * BufRateScale.kr(bufnum));
        devAmt = (deviation * LFNoise1.kr( imp) * sampstosecs);
        sig = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), trig, (begin * sampstosecs) + devAmt, 0);
        outsig = Pan2.ar(sig*amp, pan);
        Out.ar(out, [outsig[0], DelayN.ar(outsig[1], 0.002, 0.002)]);
    });

    //FUNCTIONS
    //function for use with impulse triggers
    func = {arg starttime, duration, amp, rhythms, durs, imps, begs, pans, dev;
    var now, index, dur, imp, beg, rhy, pan1;
    now = 0;
    index = 0;
    imp = imps;
    while({
    now < duration;
    }, {
    rhy = rhythms[index%rhythms.size];
    dur = durs[index%durs.size];
    imp = imps[index%imps.size];
    beg = begs[index%begs.size];
    pan1 =pans[index%pans.size];
    score.add(synth.new(now+starttime, dur).bufnum_(voice.bufnum).imp_(imp).begin_(beg).pan_(pan1).amp_(amp).deviation_(dev));
    now = now + rhy + dur;
    index = index + 1;
    })};

    /*
    func.value(0.5+(inc*0.5), 5, 0.5, [0.25],[3],[30],[4,5,6,7,8,9],[0, 1, -1],[2]);
    examples from original composition with value examples to aim for with sensor data
    func: starttime, duration, amp, rhythms, durs, imps, begs, pans, dev;
    starttime     0.5
    duration    5
    amp        0.5
    rhythms    [0.25]
    durs        [3]
    imps        [30]
    begs        [4,5,6,7,8,9]
    pans        [0, 1, -1]
    dev        [2]
    */

    //synth instantiations
    syn1 = synth.new(0, 100).bufnum_(voice.bufnum).imp_(0).begin_(0).pan_(0).amp_(4).deviation_(2).play;
    syn2 = synth.new(105, 100).bufnum_(voice.bufnum).imp_(2).begin_(0).pan_(-1).amp_(4).deviation_(2).play;
    syn3 = synth.new(210, 100).bufnum_(voice.bufnum).imp_(4).begin_(0).pan_(-1).amp_(4).deviation_(2).play;

    //arduino
    f.analog[5].active_(1);
    f.analog[2].active_(1);
    f.analog[0].active_(1);

    //right flex sensor
    //controls impulse: sample is heard clearly when sensor is fully flexed
    //posting the value of x as well as the calculated value aids in determining the best calculation to control the loop
    a = fork{
            loop{
                var bob;
                f.iterate;
                x= f.analog[5].value;
                “x:”.post;
                x.postln;
                bob = x-200;
                syn1.imp_(bob);
                “imp A: “.post;
                bob.postln;
                0.001.wait;       
            }
    };

    //center  flex sensor
    //controls panning
    b = fork{
            loop{
                var rob;
                f.iterate;
                y = f.analog[2].value;
                “y:”.post;
                y.postln;
                rob = y-400;
                syn2.pan_(rob);
                “pan B: “.post;
                rob.postln;
                0.001.wait;
           
            }
    };

    //left flex sensor
    c = fork{
            loop{
                var tod;
                f.iterate;
                z = f.analog[0].value;
                “z:”.post;
                z.postln;
                tod = (z-250)/100;
                syn3.begin_(tod);
                “begin C: “.post;
                tod.postln;
                0.001.wait;
           
            }
    };

      )
    //cease reading values
    (
    a.stop;
    b.stop;
    c.stop;
    )
    //close the serial port
    (
    f.close;
    )

  3. Controlling audio with flex sensors

    //KARST
    //Meghan Trainor, 2010
    //Arduino sensor interface

    //SERVER
    (
    Server.default = s = Server.internal.boot;
    s.waitForBoot({
    s.scope;
    FreqScope.new(400, 200, 0);
    });
    )


    //SERIAL
    (
    SerialPort.listDevices;
    d = SerialPort.devices[2];
    f = SCPyduino.new(d);  //declares f an SCPyduino object
    )

    (
    //VARIABLES + SCORE
    var score;
    //synths
    var synth, synth2, synth3;
    //samples
    var rilke;
    //functions
    var func, efunc,nfunc;
    var oldvalue = 0;
    var newvalue;
    var syn;

    //score
    score = CtkScore.new;

    //SAMPLE
    //Source = Rilke: Orpheus Sonnet pt2 11 “Many quietly acceptable methods of death have come to pass…”
    rilke = CtkBuffer.playbuf(“sounds/kar01.aif”).load;
    score.add(rilke);

    //SYNTHDEF
    // trigger synth
    synth = CtkSynthDef(\help_PlayBuf, {arg imp, begin, out = 0, bufnum = 0, pan = 0, amp =0.5, deviation = 0;
        var trig, sig, sampstosecs, devAmt;
        trig = Impulse.ar(imp);
        sampstosecs = (SampleRate.ir * BufRateScale.kr(bufnum));
        // devAmt = (deviation * TRand.kr( -1, 1,  trig) * sampstosecs);
        devAmt = (deviation * LFNoise1.kr( imp) * sampstosecs);
        sig = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), trig, (begin * sampstosecs) + devAmt, 0);
        Out.ar(out, Pan2.ar(sig*amp, pan));
        //PlayBuf.ar(numChannels, bufnum, rate, trigger, startPos, loop, doneAction)
    });



    //FUNCTION
    //function for use with impulse triggers
    func = {arg starttime, duration, amp, rhythms, durs, imps, begs, pans, dev;
    var now, index, dur, imp, beg, rhy, pan1;
    now = 0;
    index = 0;
    imp = imps;
    while({
    now < duration;
    }, {
    rhy = rhythms[index%rhythms.size];
    dur = durs[index%durs.size];
    imp = imps[index%imps.size];
    beg = begs[index%begs.size];
    pan1 =pans[index%pans.size];
    score.add(synth.new(now+starttime, dur).bufnum_(rilke.bufnum).imp_(imp).begin_(beg).pan_(pan1).amp_(amp).deviation_(dev));
    now = now + rhy + dur;
    index = index + 1;
    })};


    //starttime, duration, amp, rhythms, durs, imps, begs, pans, dev;

    //syn
    syn = synth.new(0, nil).bufnum_(rilke.bufnum).imp_(4).begin_(0).pan_(-1).amp_(4).deviation_(2).play;

    //arduino
    f.analog[0].active_(1);
    f.analog[5].active_(1);


    a = fork{
            loop{
               
                f.iterate;
                z = f.analog[0].value;
                “begin:”.post;
                z.postln;
                syn.begin_((z-250)/10);
                syn.imp_((z-250)/300);
                0.001.wait;
           
            }
    };

    b = fork{
            loop{
               
                f.iterate;
                z = f.analog[0].value;
                “pan:”.post;
                z.postln;
                syn.pan_((z-250)/300);
                //syn.imp_((z-250)/300);
                0.001.wait;
           
            }
    };


     )
    //stops the loops
    (
    a.stop;
    b.stop;
    )
    //closes the serial port
    (
    f.close;
    )

  4. SuperCollider + Arduino update

    Problem:

    f.firmataVersion;
    returns
    None

    Solution:

    download  Arduino version 0016
    install Standard Firmata from this version of Arduino

    Further Issues:

    I can’t run version 16 on my machine (solutions posted here don’t fix the java issue) but can upload Standard Firmata from any machine that can.

    Now I can start to tie sensor values to triggers in SuperCollider as with the Max/MSP prototype.

  5. Karst update

    The most significant change to the piece following the first few weeks of prototyping, experimenting and feedback is that the work will be performed walking forward through the tunnel, rather than seated at it’s mouth.  Instead of fabricated wooden forms that bulge out from the terrain, a series of sensors will reach from the back of the tunnel to the front.  This aligns more closely with the inspirational work (Horn walking from the back of the room to the front) as well as Orpheus’s passage up out of Hades.  Additionally, the length of the tunnel maps to a specific temporal event with a natural beginning and end.

    While this piece was first conceived of as being created exclusively from my own voice and breath with significant digital synthesis (after Wishart), the inclusion of the noisefloor of the site has been considered and now, as well, the sound of the exoskeletal form scraping against the wall, again referencing the audio component of Horn’s performance.

    Technical & Logistical work:
    Sensors and speakers have been ordered and shipped and once they arrive I will return to the site to conduct a next round of experiments with sounds and other performance logistics, this time using SuperCollider, rather than Max/MSP, directly with the Arduino and sensors.  Tivon has started an Arduino & SuperCollider wiki that we can use to aggregate strategies.

    I am now considering using a combination of sensors, both trigger and force, and will be focusing on how to weave all of these components together in the composition.

  6. Another Karst study, again taking unmodified source audio and dropping it into my old SuperCollider code which formed a logical “mask” for the original source audio.  Here I have used the site specific noise floor recording I made today, which includes commentary on the recordings location within the site. The unintended clipping and sampling in this and my earlier reuse of the code explores and reveals the underlying structure of the code.

  7. Karst, take 17: I spent last Friday reading 600 lines of text for Nico for the Festival project he has been working on with James Coupe.  (You can help support the project by participating in their subjective evaluation test of my synthesized voice.)  Since we were in the sound lab anyway, he was kind enough to make a new recording of my reading of the Rilke Sonnets.

    I took the new audio, without normalizing or editing out the laughter at the beginning, and simply dropped this into the original SuperCollider code.  The original included specifically setting the code to start, stop and filter at specific points in the content of the sonnets.  With this experiment there was a more stochastic process, with the sampling occuring primarily on the first line: “The machine threatens all we have gained, so long as it dare become the tyrant of spirit, rather than its servant.”

  8. Abiotica 43 (via meghatron) This is a score for my 43rd study for the piece Abiotica which was created using SuperCollider.

    Abiotica 43 (via meghatron) This is a score for my 43rd study for the piece Abiotica which was created using SuperCollider.

  9. This early study for Karst has as it’s inspiration and source a reading of one of Rilke’s Sonnets to Orpheus as well as Trevor Wishart’s Red Bird, in particular his use of the sculpted human voice.  The sole sound sources for this composition are a breath and a reading of the sonnet. The geological term karst referes to a special type of landscape that is formed by the dissolution of soluble rocks.  In this composition I am exploring the disintegration and rebuilding of the human voice in a sonic landscape just as the karst landscape is formed by the erosion and rebuilding of geological materials.

    This piece was created in SuperCollider  in March of 2010.