// title: XL Kaos Looper // author: axl99 // description: // An 'all-in-one' live looping synth with the ability to switch between the regular loop player and one that loops smaller fractions of the loop. Inspired by the Korg Kaoss Pad looper. // code: ( SynthDef('kaoslooper', {arg in=0, out=0, buf, gate=1, t_rec=0, t_reset=1, t_chop=0, plvl=1, switch=0, frombeat=0, grainsize=1, numbeats=4, numsubcycles=4, amp=1.0, wet=0.5; var dry, loopgate, time, grainlength, grainframes, subcycles, cycles, grains, trigcounter, grainstart, grainend, rlvl, xfade, playenv, prelevelenv, env, player, phase, grainer, fx; // controls loopgate and rlvl trigcounter = PulseCount.kr(t_rec, t_reset); // for the fader and for loopbuf as a trigger xfade = Lag.kr(switch.linlin(0, 1, -1, 1), 0.1); // audio input. dry = SoundIn.ar(in ! 2, 2); // loopgate is opened when closing the loop and reset by t_reset loopgate = trigcounter > 1; playenv = EnvGen.kr(Env.asr(0.05, 1.0, 0.05), loopgate); env = EnvGen.kr(Env.asr(0.04, 1, 0.04), gate, doneAction:2); prelevelenv = 1 - EnvGen.kr(Env.asr(0.1, 1, 0.1), t_chop); // controls writing into buffer rlvl = EnvGen.kr(Env.asr(0.05, 1.0, 0.05), trigcounter % 2); // outputs the length of the loop. reset by loopgate (which becomes one on first rec trig and is 1 until reset) time = Latch.kr(Timer.kr(t_rec), loopgate); // length of smallest subdivision (default 16) of loop length grainlength = time / (numbeats * numsubcycles); grainframes = (grainlength * SampleRate.ir).round(1); // make new grain starts and lengths derived from grainsize and frombeat grainstart = grainframes * frombeat * numsubcycles; grainend = grainstart + (grainframes * grainsize); // triggers on every subcycle subcycles = TDuty.kr(grainlength, loopgate, 1) * loopgate; // triggers at each loop cycle beginning + extra trigger at start of first recording cycles = Trig.kr(PulseCount.kr(subcycles, t_reset) % (numbeats * numsubcycles), 0.01) + Trig.kr(trigcounter, 0.01); // triggers on every grain (subcycles retriggers?!) grains = TDuty.kr(grainlength * grainsize, switch, 1); // players and recorder player = PlayBuf.ar(2, buf, BufRateScale.kr(buf), cycles, loop:1); //grainer is a BufRd triggered by grains phase = Phasor.ar(grains, 1, grainstart, grainend, grainstart); grainer = BufRd.ar(2, buf, phase); RecordBuf.ar(dry