{
   "labels" : [
      "percussive",
      "generative",
      "algorithmic"
   ],
   "code" : "// When The Saints Come Crawling Out\r\n// Tim Walters, 2017\r\n\r\n(\r\nServer.default.waitForBoot {\r\n\r\n\t// Name your poison\r\n\tvar durationInMinutes = 30;\r\n\r\n\tvar verb, verbBus, master, masterBus, numP, pairs, maxlevel;\r\n\r\n\tSynthDef(\\percolator, {\r\n\t\t|out = 0, gate = 1, decayCurve = -8, pan = 0, amp = 0.5, noiseDecay = 0.25, filterType = 0, filterFreq = 1000,\r\n\t\tfilterRQ = 0.05, impactDecay = 0.062, impactFreq = 250, impactWidth = 0.5, impactSweep = 0.5, shellDecay = 0.25,\r\n\t\tshellFreq = 283, shellSweep = 0.25, shellNoiseModSource = 0, trigRate = 0.5, shellNoiseModDepth = 0.5, density = 1,\r\n\t\taccentStrength = 0.5, shellModFreq = 309, shellModOffset = 0, verbSend, bodyMix=0, distance=0.5, wet = 0.25|\r\n\r\n\t\tvar noise, impact, shell, noiseEnv, impactEnv, shellEnv, shellNoiseMod, attack, triggerLag,\r\n\t\tampMod, final, trigger, accent, masterEnv, sum, phased, body, impactLevel, driver;\r\n\t\tmasterEnv = EnvGen.kr(Env.asr(0.005, 1, 0.05), gate: gate, doneAction: 2);\r\n\t\tdriver = Impulse.kr(trigRate);\r\n\t\ttrigger = driver * (Demand.kr(driver, 0, Dwhite(0, 1)) < density);\r\n\t\ttriggerLag = trigRate.reciprocal * 0.25;\r\n\t\taccent = Demand.kr(trigger, 0, Dwhite(0.0, 1.0));\r\n\t\tattack = LinExp.kr(accent, 0, 1, 0.02, 0.006);\r\n\t\tampMod = LinLin.kr(accent, 0, 1, LinLin.kr(accentStrength, 0, 1, -6, -18).dbamp, 0).dbamp;\r\n\t\tnoiseEnv = EnvGen.kr(Env.perc(attack, noiseDecay * TExpRand.kr(0.8, 1.25, trigger),\r\n\t\t\tcurve: decayCurve), gate: trigger, doneAction: 0);\r\n\t\tnoise = WhiteNoise.ar;\r\n\t\tnoise = Select.ar(filterType, [BPF.ar(noise, filterFreq, filterRQ), RLPF.ar(noise, filterFreq, filterRQ)]) * noiseEnv;\r\n\t\timpactEnv = EnvGen.kr(Env.perc(attack, impactDecay * TExpRand.kr(0.8, 1.25, trigger),\r\n\t\t\tcurve: decayCurve), gate: trigger, doneAction: 0);\r\n\t\timpact = Pulse.ar(impactEnv.range(impactFreq, impactFreq * impactSweep.midiratio), impactWidth, impactEnv);\r\n\t\tshellEnv = EnvGen.kr(Env.perc(attack, shellDecay * TExpRand.kr(0.8, 1.25, trigger),\r\n\t\t\tcurve: decayCurve), gate: trigger, doneAction: 0);\r\n\t\tshellNoiseMod = Select.ar(shellNoiseModSource, [noise, impact]) * shellFreq * shellNoiseModDepth;\r\n\t\tshell = LFTri.ar(shellEnv.range(shellFreq, shellFreq * shellSweep.midiratio) + shellNoiseMod) *\r\n\t\t(DC.ar(shellModOffset) + LFTri.ar(shellModFreq)) * shellEnv;\r\n\t\tbody = XFade2.ar(noise, shell, bodyMix);\r\n\t\timpactLevel = (LinLin.kr(distance, 0, 1, 3, -9) + TRand.kr(-2, 2, trigger)).dbamp;\r\n\t\t//impactLevel = LinLin.kr((LinLin.kr(distance, 0, 1, 0.2, 0.8) + LFNoise2.kr(Rand(0.1, 0.3), 0.2)), 0, 1, 1, 6, -12).dbamp;\r\n\t\tsum = LPF.ar(Mix.ar([impact * impactLevel, body]), LinExp.kr(distance, 0, 1, 18000, 6000), mul: -10.dbamp);\r\n\t\tfinal = Pan2.ar(BPeakEQ.ar(sum, 1800, 4, -6), TRand.kr(-1, 1, Lag.kr(trigger, triggerLag * 0.125)), masterEnv * amp * ampMod * AmpCompA.kr(shellFreq));\r\n\t\tOffsetOut.ar(verbSend, final * LinLin.kr(distance, 0, 1, -18, -6).dbamp * wet);\r\n\t\tOffsetOut.ar(out, final * LinLin.kr(distance, 0, 1, 0, -6).dbamp);\r\n\t}).add;\r\n\r\n\tSynthDef(\\verb, {\r\n\t\t|in, gate=1, out = 0|\r\n\t\tvar input = In.ar(in, 2);\r\n\t\tvar releaser = DetectSilence.ar(gate + input, doneAction: 2);\r\n\t\tOffsetOut.ar(out, GVerb.ar(input, roomsize: 80, drylevel: 0, earlyreflevel: 1, taillevel: -3.dbamp))\r\n\t}).add;\r\n\r\n\tSynthDef(\\master, {\r\n\t\t|in, gate=1, out=0|\r\n\t\tvar input = In.ar(in, 2);\r\n\t\tvar shaped = Compander.ar(input, input, -12.dbamp, 1, 0.75, 0.1, 0.3);\r\n\t\tvar limited = Limiter.ar(shaped, -2.dbamp);\r\n\t\tvar releaser = DetectSilence.ar(gate + input, doneAction: 2);\r\n\t\tOffsetOut.ar(out, limited)\r\n\t}).add;\r\n\r\n\tServer.default.sync;\r\n\r\n\tverbBus = Bus.audio(Server.default, 2);\r\n\tmasterBus = Bus.audio(Server.default, 2);\r\n\tverb = Synth(\\verb, [\\in, verbBus.index, \\out, masterBus.index], Server.default, \\addToTail);\r\n\tmaster = Synth(\\master, [\\in, masterBus.index, \\out, 0], Server.default, \\addToTail);\r\n\r\n\tServer.default.sync;\r\n\t1.wait;\r\n\r\n\tnumP = 4;\r\n\r\n\tPpar({ |i|\r\n\t\tvar durationInSeconds = durationInMinutes * 60;\r\n\t\tPbind(\r\n\t\t\t\\time, Ptime.new,\r\n\t\t\t\\instrument, \\percolator,\r\n\t\t\t\\freq, Pfunc({ |e| (e[\\time] < durationInSeconds).if {\r\n\t\t\t\t110 } {\r\n\t\t\t\t(i == 0).if {\r\n\t\t\t\t\tverb.release;\r\n\t\t\t\t\tmaster.release;\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t1.wait;\r\n\t\t\t\t\t\tverbBus.notNil.if { verbBus.free };\r\n\t\t\t\t\t\t5.wait;\r\n\t\t\t\t\t\tmasterBus.notNil.if { masterBus.free };\r\n\t\t\t\t\t}.fork;\r\n\t\t\t\t};\r\n\t\t\t\tnil\r\n\t\t\t}\r\n\t\t\t}),\r\n\t\t\t\\agitation, Pfunc({ |e| (e[\\time] == 0).if { 0 } { [0, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7].choose } }),\r\n\t\t\t\\agitationMult, Pfunc({ |e| 2 ** (7 - e[\\agitation]) }),\r\n\t\t\t\\agitationComp, Pfunc({ |e| e[\\agitation].linlin(0, 7, -6.dbamp, 0.dbamp) }),\r\n\t\t\t\\dur, Pfunc({ |e| (rrand(0, 2).nthPrime * [1, 2, 4, 8].choose).min(durationInSeconds - e[\\time]) }),\r\n\t\t\t\\legato, (i == 0).if {\r\n\t\t\t\tPrand([1.0, 1.25, 1.5], inf)\r\n\t\t\t} {\r\n\t\t\t\tPrand([0.25, 0.5, 0.75, 1.0] / i, inf)\r\n\t\t\t},\r\n\t\t\t\\noiseDecay, Pfunc({ |e| exprand(0.25, 20.0) * e[\\agitationMult] }),\r\n\t\t\t\\filterFreq, Pexprand(40, 5000, inf),\r\n\t\t\t\\filterRQ, Pexprand(0.05, 2.0, inf),\r\n\t\t\t\\impactDecay, Pfunc({ |e| exprand(0.02, 0.08) * e[\\agitationMult] }),\r\n\t\t\t\\impactFreq, Pexprand(40, 5000, inf),\r\n\t\t\t\\impactWidth, Pexprand(0.05, 0.95, inf),\r\n\t\t\t\\impactSweep, Pexprand(0.25, 4.0, inf),\r\n\t\t\t\\shellDecay, Pfunc({ |e| exprand(0.25, 20.0) * e[\\agitationMult] }),\r\n\t\t\t\\shellFreq, Pexprand(60, 1000, inf),\r\n\t\t\t\\shellNoiseModSource, [0, 1].choose,\r\n\t\t\t\\shellNoiseModDepth, Pexprand(0.1, 1.0, inf),\r\n\t\t\t\\shellModFreq, Pexprand(40, 5000, inf),\r\n\t\t\t\\shellModOffset, Pwhite(0.0, 1.0, inf),\r\n\t\t\t\\shellSweep, Pexprand(0.125, 4.0, inf),\r\n\t\t\t\\amp, Pfunc({ |e| 0.dbamp * e[\\agitationComp] }),\r\n\t\t\t\\accentStrength, Pwhite(0.0, 1.0),\r\n\t\t\t\\trigRate, Pfunc({ |e|\r\n\t\t\t\trrand(0, 3).nthPrime\r\n\t\t\t\t* [0.25, 1/3, 0.5, 2/3, 1, 4/3, 1.5, 5/3, 2, 7/3, 2.5, 8/3, 3, 10/3, 11/3, 4].choose\r\n\t\t\t\t* e[\\agitationMult].reciprocal\r\n\t\t\t}),\r\n\t\t\t\\decayCurve, Pexprand(-12, -4),\r\n\t\t\t\\density, Pfunc({ |e| rrand(e[\\agitation].linlin(0, 1, 1, 0.15), 1) }),\r\n\t\t\t\\server, Server.default,\r\n\t\t\t\\verbSend, verbBus.index,\r\n\t\t\t// -1 is all noise, 1 is all shell\r\n\t\t\t\\bodyMix, Pwhite(-1, 1),\r\n\t\t\t\\distance, Pwhite(0, 1),\r\n\t\t\t\\wet, -6.dbamp,\r\n\t\t\t\\addAction, \\addToHead,\r\n\t\t\t\\out, masterBus.index,\r\n\t\t)\r\n\t} ! numP).play;\r\n};\r\n)",
   "is_private" : null,
   "id" : "1-57t",
   "author" : "walters",
   "name" : "When The Saints Come Crawling Out",
   "description" : "Submission for WESU algorithmic music show.",
   "ancestor_list" : []
}
