-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