{
   "author" : "tedthetrumpet",
   "name" : "Livecode setup, with comments",
   "ancestor_list" : [],
   "description" : "My personal setup file for livecoding as at 8/03/2017, with some explanatory comments",
   "labels" : [
      "livecode algorave"
   ],
   "code" : "/* my personal setup file for livecoding in sc, as at 8/03/2017, with some explanatory comments\r\n\r\nThe synths I use, in a separate file that gets loaded below: \\slice \\dice \\warp \\bf \\bform \\rh \\rh2\r\n\r\nThree effects are set up ready to go, reverb, comb delay and decimator. The two latter effects can be controlled with patterns:\r\n\r\nPbindef(\\e, \\type, \\set) controls Synth \\echo on ~ebus (args: \\delay, \\decay, \\amp)\r\nPbindef(\\m, \\type, \\set) controls Synth \\mate on ~mbus (args: \\rate, \\bits, \\amp)\r\nNdef(\\r) reverb node, listening to ~rbus\r\n\r\nFolders with drum(ish) hits, stereo or duplicated mono: \"hitz01 soh hamburg iowaphil emf nl tw hitz02 hitz01a\". hitz02 and hitz01a pre-ordered into simple 32 beat drum sequence.\r\n\r\nFunctions: ~changebufs, ~listbufs, ~listloops, ~rrest, ~rdur\r\n\r\nLoops: a folder of roughly two-bar loops for slicing and/or granulating, mostly excerpts from old tv theme tunes. These get loaded twice, as stereo buffers and also as pairs of mono buffers. (Because that's the only way I could figure out how to granulate in stereo!?)\r\n\r\n*/\r\n\r\n(//setup\r\nPdef.all.clear; Pdefn.all.clear; Ndef.all.clear; // not sure if this actually works?\r\n// quantize changes to even four beat bars\r\nPbindef.defaultQuant_(4); Pdefn.defaultQuant_(4);\r\ns.waitForBoot{\r\n\tvar path, files;\r\n\tf = #[\"lcode07synths.scd\"]; // load synths and fx from separate file\r\n\tf.do {|x| x.loadRelative};\r\n\ts.sync;\r\n\r\n\tBuffer.freeAll;\r\n\ts.sync;\r\n\r\n\t// load loops\r\n\tpath = \"../sldiwaloops/\".resolveRelative;\r\n\tfiles = (path ++ \"*.aiff\").pathMatch ++ (path ++ \"*.aif\").pathMatch;\r\n\t~l = files.collect({ |i|  Buffer.read(s, i)});\r\n\t~l2 = files.collect({ |i| 2.collect( {|c| Buffer.readChannel(s, i, channels: [c])}) });\r\n\ts.sync;\r\n\r\n\t// load samples\r\n\r\n\t~thebufs;\r\n\t~changebufs = {\r\n\t\t|x=\"hitz01a\"|\r\n\t\tif ( \"hitz01 soh hamburg iowaphil emf nl tw hitz02 hitz01a\".find(x) != nil, // checking the subfolder is correct\r\n\t\t\t{\tvar path = \"../bfsamples/\".resolveRelative ++ x ++ \"/\";\r\n\t\t\t\tvar files = (path ++ \"*.aiff\").pathMatch ++ (path ++ \"*.aif\").pathMatch;\r\n\t\t\t\tfiles = files.sort; // get them in order of name, not modified date!\r\n\t\t\t\t// first, free all the buffers\r\n\t\t\t\t~thebufs.do({|i| i.free});\r\n\t\t\t\t// now, read the new files in\r\n\t\t\t\t~thebufs = files.collect({ |i|  Buffer.read(s, i)});\r\n\t\t\t\t~bufs = ~thebufs.collect(_.bufnum);\r\n\t\t\t\t~listbufs.();\r\n\t\t\t},\r\n\t\t\t{\"that's not a sample folder\".error; nil});\r\n\t};\r\n\t~changebufs.(); // can use this to change buffers between songs/sets\r\n\r\n\t~listbufs = {\r\n\t\t([~bufs] ++[~thebufs.collect(_.path).collect(_.asPathName).collect(_.fileName)]).flop.do(_.postln);\r\n\t\tnil\r\n\t};\r\n\r\n\t~listloops = {\r\n\t([~l.collect(_.bufnum)]++[~l.collect(_.path).collect(_.asPathName).collect(_.fileName)]).flop.do(_.postln);\r\n\t\tnil\r\n\t};\r\n\r\n\t// mixer node for final reverb\r\n\t~rbus = Bus.audio(s, 2);\r\n\tNdef(\\r).put(0, { InFeedback.ar(~rbus, 2) }).fadeTime_(0.2).play;\r\n\tNdef(\\r).filter(1, { |x| JPverb.ar(x, t60:0.1, size:0.8)}).set(\\wet1, 0.2);\r\n\r\n\t// fx setup\r\n\t~ebus = Bus.audio(s, 2);\r\n\t~e=Synth.tail(s, \\echo, [in: ~ebus, delay:1/t.tempo/4, out: ~rbus]); // .tail? not sure why?\r\n\tPbindef(\\e,\r\n\t\t\\type, \\set,\r\n\t\t\\id, ~e.nodeID,\r\n\t\t\\args, #[\\delay, \\decay, \\amp, \\out],\r\n\t\t\\out, ~rbus\r\n\t).play;\r\n\r\n\t~mbus = Bus.audio(s, 2);\r\n\t~m=Synth(\\mate, [in: ~mbus, out: ~rbus]);\r\n\tPbindef(\\m,\r\n\t\t\\type, \\set,\r\n\t\t\\id, ~m.nodeID,\r\n\t\t\\args, #[\\rate, \\bits, \\amp],\r\n\t\t\\amp, 0.8,\r\n\t\t\\out, ~rbus\r\n\t).play;\r\n\r\n\ts.sync;\r\n\r\n};\r\n\r\n// rhythm function for isRest, ~rrest.() defaults to 8, or use ~r.(16), ~r.(7) etc\r\n// creates syncopated rhythms by concatenating two and three beat cells, always with a downbeat\r\n~rrest = { |a=8|\r\n\tvar rhythm;\r\n\ta=(a-1).mod(16);\r\n\trhythm = if ( a>7,\r\n\t\t{({[[1,0,0], [1,0,1]].choose}!4 ++ [[1,0].dup.flatten]).scramble.flatten.collect(_.booleanValue.not) },\r\n\t\t{({[[1,0,0], [1,0,1]].choose}!2 ++ [[1,0]]).scramble.flatten.collect(_.booleanValue.not) }\r\n\t);\r\n\trhythm=rhythm[0..a];\r\n};\r\n\r\n// rhythm function for dur, ~rdur.() defaults to 8, or use ~r.(16), ~r.(7) etc\r\n// uses the same function as above to work with durations instead of isRest\r\n\r\n~rdur = { |b=8|\r\n\tvar x;\r\n\tx = ~rrest.(b).collect(_.not.asInteger);\r\n\tx = x.indicesOfEqual(1).replace(0, x.size).rotate(-1).differentiate;\r\n};\r\n\r\nt=TempoClock.default.tempo_(140/60);\r\n\r\n// a collection of jazz chords in dorian mode, make some sort of sense if played in order\r\n~jz=[\r\n\t[0,4,6,9],  [0,4,5,9],  [0,3,6,9],  [0,3,4,8],  [-1,3,4,8],  [-1,2,4,8],  [-1,2,5,8],  [-1,2,5,7],  [-1,2,4,7],  [-2,2,4,7],  [-2,1,4,7],  [-3,0,3,6],  [-3,1,2,6],  [-3,1,3,6],  [-3,2,3,6],  [-2,2,3,6],  [-1,2,3,7],  [0,2,4,8],  [0,3,5,8],  [2,4,6,8],  [3,4,6,9],  [3,5,7,10]\r\n];\r\n\r\nnil;\r\n)\r\n\r\n//////////// notes and examples /////////////////////////\r\n// how to use the granulator, syntax for passing pairs of buffers (L&R) is a bit fiddly!\r\nx=Synth(\\warp, [\\buf, [~l2[7]], \\rate, -0.05, \\amp, 0.4])\r\nx.setn(\\buf, ~l2[3])\r\nPbindef(\\w, \\type, \\set, \\id, x.nodeID, \\args, #[\\buf, \\rate, \\freq, \\amp])\r\nPbindef(\\w, \\dur, 1/2, \\note, Pbrown(0,12,1))\r\nPbindef(\\w).quant_(0).play\r\nPbindef(\\w, \\buf, [~l2[2]])\r\nPbindef(\\w, \\amp,  0.4 * Pseries(25, -1, 26)/25) // fadeout, x still running\r\n// useful bits\r\nSynthDescLib.global.at(\\mate)\r\nPbindef(\\w).asCompileString.newTextWindow\r\n\r\n// series of amplitude values for a basic snare pattern\r\n2312.asBinaryDigits(16)/10\r\n// a metronome\r\nPbindef(\\tmetro, \\dur, 1, \\legato, 0.01, \\note, Pseq([36,30,30,30], inf), \\amp, 0.5).play(t, quant:4)\r\n// very useful syntax, create a new random rhythm every four bars\r\nPbindef(\\z, \\buf, Pn(Plazy({Pseq({~bufs.choose}!16,4)})))",
   "is_private" : null,
   "id" : "1-56y"
}
