038 Moulding Breath

Description

Today is International Dance Day!
Dance is movement.
All movement also speaks of stillness.
Let each of us feel for ourselves what dance is and how to dance.
Let the friction caused by contradictions become colors of our creation.
Let us have those colors.
And yes: dance can be a way to touch the mystery of life.
Happy dance day!


Täna on rahvusvaheline tantsupäev!
Tants on liikumine.
Igasugune liikumine räägib ka vaikusest.
Las jääda igaühe enda tunnetada, mis on tants ja kuidas tantsida.
Saagu vastuoludest tekkinud hõõrdumistest värvid meie loomingu jaoks.
Las neid värve olla.
Ning jah: tants võib olla viis puudutada elu mõistatust.
Head tantsupäeva!

Source Code

// Dependencies: FxChain quark

BBSMBTrumpetGrainDelay{
    var <db, <in, <out, <minAmp, <maxAmp, <threshold, <monitorOut, <monitorLevel;
    var <fxChain;
    var <monitorFxChain;
    var <grainDelay;
    var <fadeInTime = 1;
    var <fadeOutTime = 60;

    *new{|db=0, in=2, out=0, minAmp=0, maxAmp=1, threshold=0.05, monitorOut=0, monitorLevel=1|
        ^super.newCopyArgs(db, in, out, minAmp, maxAmp, threshold, monitorOut, monitorLevel).init;
    }
    
    init{
        this.prCreateFxChain;
        this.prCreateMonitorFxChain;
        this.prCreateGrainDelay;
    }

    prCreateGrainDelay{
        grainDelay = BBSMBGrainDelay.new(
            in: in,
            out: fxChain.in,
            group: fxChain.group,
            monitorOut: monitorFxChain.in,
            minAmp: minAmp,
            maxAmp: maxAmp,
            threshold: threshold
        );
    }

    prCreateMonitorFxChain{
        monitorFxChain = FxChain.new(
            level: 0,
            out: out,
            fadeInTime: fadeInTime,
            fadeOutTime: fadeOutTime,
        );
    }

    prCreateFxChain{
        fxChain = FxChain.new(
            level: db.dbamp,
            out: out,
            fadeInTime: fadeInTime,
            fadeOutTime: fadeOutTime,
        );
        fxChain.add(\flanger, [
            \feedback, 0.08,
            \depth, 0.04,
            \rate, 0.03,
            \decay, 0.01,
            \mix, 0.3,
        ]);
        fxChain.add(\jpverb,[
            \revtime, Pwhite(1.0, 4.0),
            \mix, Pwhite(0.1, 0.4),
        ]);
    }

    play {
        fork{
            1.wait;
            grainDelay.play([9, 10, 11, 12]);
        }
    }

    free {
        fork{
            grainDelay.free;
            5.wait;
            fxChain.free;
            monitorFxChain.free;
        }
    }
}


BBSMBGrainDelay {

    var <in;
    var <>out;
    var <>monitorOut;
    var <monitorLevel;
    var <>group;
    var <monitorGroup;
    var <maxDelay;
    var <minAmp;
    var <maxAmp;
    var <>speedlim;
    var <>threshold;
    var <>minGrainDur;
    var <>maxGrainDur;
    var <minDur;
    var <maxDur;
    var <fadeInTime;
    var <>fadeOutTime;
    var <attack;
    var <rates;
    var <buf;
    var <recId;
    var recPos;
    var recorder;
    var <>server;
    var setRecPos;
    var <>minRelease = 3;
    var <>maxRelease = 8;
    var <mbDeltaTrigs;
    var bufFreed = true;
    var <mbIDs=#[9, 10, 11, 12, 13, 14, 15, 16];

    *new{|in=2, out=0, monitorOut=0, monitorLevel=1, group=1, monitorGroup=1, maxDelay=10, minAmp=0, maxAmp=1, speedlim=0.1, threshold=0.05, minGrainDur=0.01, maxGrainDur=0.05, minDur=2, maxDur=4, fadeInTime=1, fadeOutTime=1, attack=0.2, rates=#[0.25, 0.5, 1, 2]|
    ^super.newCopyArgs(in, out, monitorOut, monitorLevel, group, monitorGroup, maxDelay, minAmp, maxAmp, speedlim, threshold, minGrainDur, maxGrainDur, minDur, maxDur, fadeInTime, fadeOutTime, attack, rates).init;
}

init{
    server ?? {server = Server.default};
    buf = Buffer.alloc(server, maxDelay * server.sampleRate);
    bufFreed = false;
    fork{
        server.sync;
        this.prCreateRecorder;
        this.prCreateOscFunc;
        this.prCreateMBDeltaTrigs;
    }
}

play{
    arg mbs=#[9,10,11,12,13,14,15,16];
    mbs.do{|id| 
        var index = mbIDs.indexOf(id);
        mbDeltaTrigs[index].play;
    };
    recorder.set(\gate, 1);
}

monitorLevel_ {|val|
    recorder.set(\amp, val);
}

minAmp_ {|val|
    mbIDs.do{|i| i.minAmp = val}
}

maxAmp_ {|val|
    mbIDs.do{|i| i.maxAmp = val}
}

prCreateRecorder {
    recId = rrand(0, 10000);
    recorder = Synth(\rec, [
        \in, in,
        \id, recId,
        \buf, buf,
        \out, monitorOut,
        \amp, 0,
        // \amp, monitorLevel,
        \attack, fadeInTime,
    ], target: monitorGroup);
}

prCreateOscFunc {
    setRecPos = OSCFunc( {|msg, time|
        if(msg[2]==recId){
            recPos = msg[3];
        };
    }, '/recPos');
}

prCreateMBDeltaTrigs{
    mbDeltaTrigs = mbIDs.collect{|id, idx|
        MBDeltaTrig.new(
            speedlim: speedlim, 
            threshold: threshold,
            minibeeID: id,
            minAmp: minAmp,
            maxAmp: maxAmp,
            function: {|dt, minAmp, maxAmp|
                this.player(dt, minAmp, maxAmp, id);
            };
        );
    }
}

player {|dt = 0, minAmp = -30, maxAmp = 0, mbID=9|
    var release = dt.linlin(0.0, 1.0, minRelease, maxRelease);
    var dbMax = dt.linlin(0.0, 1.0, minAmp, maxAmp);
    var db = Pseg([-70, dbMax, -70], [attack, release]);
    var graindur = exprand(minGrainDur, minGrainDur);

    Pfindur(
        dt.linlin(0.0, 1.0, minDur, maxDur),
        Pbind(
            \instrument, \playbuf,
            \buf, buf,
            \loop, 1,
            \db, db,
            \rate, Pfunc{ 
                var bus = BBS.mbData[mbID].xbus.getSynchronous;
                var rateCtrl = bus.linlin(0.0, 1.0, 0, rates.size-1);
                rates[rateCtrl];
            },
            \dur, graindur,
            \attack, Pkey(\dur),
            \release, Pkey(\dur),
            \legato, 2,
            \startPos, Pfunc{|ev|
                var delayTime = rrand((ev.dur * ev.legato), ev.buf.duration);
                var startPos = recPos - (delayTime * server.sampleRate);
                startPos = startPos.mod(ev.buf.numFrames)
            },
            \out, out,
            \group, group,
        )
    ).play
}

freeMB{|id|
    var index = mbIDs.indexOf(id);
    mbDeltaTrigs[index].free;
}

free{|fadeOutTime=5|
    fork{
        mbDeltaTrigs.do(_.free);
        recorder.release(fadeOutTime);
        (fadeOutTime*4).wait;
        buf.free({bufFreed = true});
        setRecPos.clear;
    }
}
}