-odac -iadc -d ; Initialize the global variables. sr = 44100 kr = 11025 ksmps = 4 nchnls = 2 0dbfs = 1 zakinit 16, 16 ; 16 audio pipelines, 16 control pipelines gibasfreq = 63 gisecperbeat = 0.22 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; instr 11 ; a modulation source klfo5 init 0 klfo1 lfo 1, 3.6 + klfo5, 1 klfo2 lfo 1, 3.1 + klfo1, 1 klfo3 lfo 1, 2.7 + klfo2, 1 klfo4 lfo 1, 0.3 + (klfo3 * 0.2), 1 klfo5 lfo 1, 2.3 + (klfo4 * 1.5), 1 klfo6 lfo 1, 0.45, 1 klfo7 lfo 1, 0.77, 1 klfo8 lfo 1, 1.2, 1 zkw klfo1, 0 zkw klfo2, 1 zkw klfo3, 2 zkw klfo4, 3 zkw klfo5, 4 zkw klfo6, 5 zkw klfo7, 6 zkw klfo8, 7 ; two rising ramps: kramp1 linseg 0, 5, 1, 1, 1 kramp2 linseg 0, 15, 1, 1, 1 ; two falling ramps -- assumption is that instr will be running ; for at least 17 seconds: kramp3 linseg 1, (p3 - 5), 1, 5, 0, 1, 0 kramp4 linseg 1, (p3 - 17), 1, 15, 0, 1, 0 zkw kramp1, 8 zkw kramp2, 9 zkw kramp3, 10 zkw kramp4, 11 endin ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; instr 15 ; a step sequencer kfreq init 63 kpstepnum init 0 iplooplen = 16 kploopstart init 0 iupdowntip = 0.3 ; a value between -0.5 and 0.5 works. >1 is always forward, <-1 is always backward. irthmtabnum = 23 krstepnum init 0 irlooplength = 13 kstepdur init 1 irthmdiv = gisecperbeat ; seqtime reads a time value out of table 23 (multiplying the time unit by irthmdiv). ; as a result, kpulse goes to 1 with a rhythm controlled by table 23. kpulse is ; then used to switch schedkwhen to true ; ktrig_out seqtime ktime_unit, kstart, kloop, kinitndx, kfn_times kpulse seqtime irthmdiv, 0, irlooplength, 0, irthmtabnum ; schedkwhen is triggered by kpulse. It outputs a note to instr 21. The value in ; gkpulsedur is supposed to be written to by the _previous_ note -- or rather, each ; note in instr 21 writes a value into gkpulsedur that will be used to set the duration ; of the next note. But there's a problem, which is that the table opcode doesn't know ; it's supposed to loop back after 11 steps, whereas the seqtime opcode can do that. ;schedkwhen ktrigger, kmintim, kmaxnum, kinsnum, kwhen, kdur \ ; [, ip4] [, ip5] [...] kthisstepdur = kstepdur * irthmdiv schedkwhen kpulse, 0, 7, 21, 0, kthisstepdur, 0.3, 0, kpstepnum schedkwhen kpulse, 0, 7, 21, 0, kthisstepdur, 0.3, 1, kpstepnum schedkwhen kpulse, 0, 7, 21, 0, kthisstepdur, 0.3, 2, kpstepnum ; here we keep track of what step we've reached in the rhythm loop. Each time we update ; the stepnum, the value of kstepdur will also change, because we're looking up the length of the next ; step in the table. kbacklfo lfo 1, 1, 0 kbacklfo = kbacklfo + iupdowntip if (kpulse == 0) kgoto noupdate ; the pitch step can move backward or forward: kpstepnum = ((kbacklfo < 0) ? (kpstepnum - 1) : (kpstepnum + 1)) if (kpstepnum >= 0) kgoto checkupperpitchbound kpstepnum = kploopstart + iplooplen - 1 checkupperpitchbound: if (kpstepnum < (kploopstart + iplooplen)) kgoto nopitchreset kpstepnum = kploopstart nopitchreset: ; and now the rhythm step, which always moves forward: krstepnum = krstepnum + 1 if (krstepnum < irlooplength) kgoto noupdate krstepnum = 0 noupdate: kstepdur table krstepnum, irthmtabnum endin ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; instr 21 ; a simple tone generator ; whose output to zak is chosen by ; a p-field idur = p3 iamp = p4 izakout = p5 ; we're going to use p5 to set up the output, the inumtab = p5+2 ; pitch table input, and the selection of LFOs identab = p5+12 ilfo1 = p5 ilfo2 = p5+1 ilfo3 = p5+2 ilfo4 = p5+3 istep = p6 ioctmult = 4 klfo1 zkr ilfo1 klfo2 zkr ilfo2 klfo3 zkr ilfo3 klfo4 zkr ilfo4 iramp1 zir 9 inum table istep, inumtab, 0, 0, 1 iden table istep, identab, 0, 0, 1 ifreq = gibasfreq * ioctmult * inum / iden ; tone generation: imodraw zir ilfo1 imod = floor((imodraw + 2) * 2.2) icar = 1 ibus3 zir ilfo2 iatktime = (ibus3 + 1.1) * 0.03 ibus1 zir ilfo3 ireltime = ((ibus1 + 1.6) * 0.12) + 0.1 irawdur = idur - (iatktime + ireltime) ienvdur = (irawdur < 0.003 ? 0.003 : irawdur) kfmindex linseg 2, 0.05, 0.5, (idur - 0.05), 0.1, 1, 0 ifaderamp zir 11 kfmindex = kfmindex * ifaderamp asig foscili 1, ifreq, icar, imod, (kfmindex + klfo4), 1 ; (klfo4 * 2), 1 kampenv linsegr 0, iatktime, iamp, ienvdur, iamp * 0.6, ireltime, 0 asig = asig * kampenv * ifaderamp ; output zawm asig, izakout endin ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; instr 101 ; a mixer with a reverb and a delay ; get the inputs: a1 zar 0 a2 zar 1 a3 zar 2 ; clear the buffers for the next pass: zacl 0, 7 amixL = a1 + (a2 * 0.6) amixR = a3 + (a2 * 0.6) ; stereo delay: idelfdbk = 0.1 idelamp = 0.6 adelL delayr (gisecperbeat * 2) adelL = adelL * idelamp delayw a1 + (adelL * (idelfdbk + 0.35)) adelR delayr (gisecperbeat * 4) adelR = adelR * idelamp delayw a3 + (adelR * idelfdbk) ; apply reverb: aRevL, aRevR reverbsc amixL, amixR, 0.7, 10000 ; automate a fadein of the dry signal: kramp1 zkr 9 adryL = (amixL + adelR) * kramp1 adryR = (amixR + adelL) * kramp1 ; envelope the output smoothly: kdeclick linsegr 0, 0.01, 1, (p3 - 0.01), 1, 0.1, 0 aoutL = (adryL + (0.2 * aRevL)) * kdeclick aoutR = (adryR + (0.2 * aRevR)) * kdeclick outs aoutL, aoutR endin ; Table #1, a sine wave. f1 0 1024 10 1 ; Table #2, a 16-step sequence of JI ratios. f2 0 16 -2 1 3 5 8 1 2 9 5 2 15 3 7 3 5 11 9 f12 0 16 -2 1 2 4 5 1 1 8 4 1 8 2 5 2 4 8 8 f3 0 16 -2 5 7 15 2 3 5 11 3 5 9 2 9 13 7 3 11 f13 0 16 -2 4 4 8 1 2 3 8 2 2 4 1 5 8 4 2 8 f4 0 16 -2 3 2 9 5 7 4 13 2 3 5 9 6 1 15 1 7 f14 0 16 -2 2 1 4 2 4 3 8 1 2 4 8 5 1 16 1 8 ; Table #23, a set of step times. f23 0 16 -2 2 1 1 2 1 1 1 2 1 3 1 1 2 1 4 4 i11 0 25 i15 0 23 i101 0 26 f0 27 e