{
   "id" : "1-4Rs",
   "is_private" : null,
   "code" : "// switching to mono cz SinedPink.aiff is boring\r\n\r\n// two BufRd-based synths, one percussive, one smoother:\r\n(\r\nSynthDef(\\bufRdperc1, {| out = 0, bufnum = 0, rate=1, inter=2, posfrac = 0.5, dur = 1, amp = 0.9|\r\n\tvar widthfrac = (dur/BufDur.ir(bufnum)) * rate;\r\n\tvar sig = Splay.ar([\t\t\t\r\n\t\tBufRd.ar(1, bufnum, Phasor.ar(\r\n\t\t\t\t0, \r\n\t\t\t\t(BufRateScale.kr(bufnum) * rate), \r\n\t\t\t\t(posfrac * BufSamples.kr(bufnum)), \r\n\t\t\t\t(posfrac * BufSamples.kr(bufnum)) + (widthfrac * BufSamples.kr(bufnum))), \r\n\t\t\t1, inter)\r\n\t]);\r\n\tOut.ar(out, sig  \r\n\t\t\t\t* EnvGen.kr(Env.perc,1,1,0,dur,2)\r\n\t\t\t\t* amp\r\n\t)\r\n}).add;\r\n\r\nSynthDef(\\bufRdsmooth1, {| out = 0, bufnum = 0, rate=1, inter=2, posfrac = 0.5, dur = 1, amp = 1|\r\n\tvar widthfrac = ((dur/2)/BufDur.ir(bufnum)) * rate;\r\n\tvar forward = BufRd.ar(1, bufnum, Phasor.ar(\r\n\t\t\t\t0, \r\n\t\t\t\t(BufRateScale.kr(bufnum) * rate.abs), \r\n\t\t\t\t(posfrac * BufSamples.kr(bufnum)) - (widthfrac * BufSamples.kr(bufnum)), \r\n\t\t\t\t(posfrac * BufSamples.kr(bufnum)) + (widthfrac * BufSamples.kr(bufnum))), \r\n\t\t\t1, inter);\r\n\tvar backward = BufRd.ar(1, bufnum, Phasor.ar(\r\n\t\t\t\t0, \r\n\t\t\t\t(BufRateScale.kr(bufnum) * rate.abs * (-1)), \r\n\t\t\t\t(posfrac * BufSamples.kr(bufnum)) + (widthfrac * BufSamples.kr(bufnum)), \r\n\t\t\t\t(posfrac * BufSamples.kr(bufnum)) - (widthfrac * BufSamples.kr(bufnum))), \r\n\t\t\t1, inter);\r\n\tvar sound = BiPanB2.ar(forward,backward,FSinOsc.kr(dur));\r\n\tsound = sound * EnvGen.kr(Env.sine,1,1,0,dur,2);\r\n\tsound = sound * amp;\r\n\tOut.ar(out, sound);\r\n}).add;\r\n\r\n)\r\n\r\n//\r\n// two functions that generate Pbinds\r\n(\r\n~make1perc = { |durs, lib|\r\n\tvar n   = durs.size;\r\n\tPbind(\r\n\t  \\bufnum,\tPatternProxy(Pseq({lib.choose}!n,inf)),\r\n\t  \\rate,\tPatternProxy(Pseq([1],inf)),\r\n\t  \\posfrac,\tPatternProxy(Pseq({512.rand/512}!n,inf)),\r\n\t  \\dur, \tPatternProxy(Pseq(durs,inf)),\r\n\t  \\amp,\tPatternProxy(Pseq({(1..3).choose}!n,inf)), \r\n\t  \\instrument,PatternProxy(Pfunc({ |ev| (\"bufRdperc\" ++ ev[\\bufnum].numChannels) }))\r\n        );\r\n};\r\n\r\n~make1smooth = { |durs, lib|\r\n\tvar n   = durs.size;\r\n\tPbind(\r\n\t  \\bufnum,\tPatternProxy(Pseq({lib.choose}!n,inf)),\r\n\t  \\rate,\tPatternProxy(Pseq([1],inf)),\r\n\t  \\posfrac,\tPatternProxy(Pseq({512.rand/512}!n,inf)),\r\n\t  \\dur, \tPatternProxy(Pseq(durs,inf)),\r\n\t  \\amp,\tPatternProxy(Pseq({(1..3).choose}!n,inf)), \r\n\t  \\instrument,PatternProxy(Pfunc({ |ev| (\"bufRdsmooth\" ++ ev[\\bufnum].numChannels) }))\r\n        );\r\n};\r\n\r\n//\r\n//\r\n// the function with the hack to get at, and modify while running, the internals of the patterns\r\n\r\n~frac = { |n = 1|\r\n\t~players.do{ |i|\r\n\t\tvar z = i.stream.slotAt('receiver'); // the hack. it wd be nice to have legal method for this\r\n\t\tz.patternpairs.at(z.patternpairs.indexOf('posfrac') + 1).source = Pseq({512.rand/512}!n,inf)\r\n\t}\t\t\r\n};\r\n\r\n)\r\n\r\n//\r\n//\r\n//\r\n// fun things to execute at runtime\r\n//\r\n\r\n/*\r\n~buffers is an array of mono Buffers. if you don't have any, you can do\r\n~buffers = [Buffer.read(s, Platform.resourceDir ++ \"/sounds/a11wlk01.wav\")];\r\n*/\r\n\r\n\r\n[1/8, 1/4, 1/2].do{|i| ~players = ~players.add((~make1perc.([i], [~buffers.choose])).play)}\r\n\r\n\r\n1.do{~players = ~players.add((~make1smooth.([1], [~buffers.choose])).play)}\r\n\r\n\r\n~frac.();\r\n~frac.(x = 1);\r\n~frac.(x = x*2);\r\n~frac.(x = x+2);\r\n~frac.(x.postln);\r\n\r\n\r\n~players.pop.stop;",
   "labels" : [
      "patterns",
      "patternproxies",
      "hacks"
   ],
   "description" : "possibly too-detailed demo of using functions to generate patterns, and then a function to modify the internals of the resulting EventStreamPlayers while they are running.   \r\n  \r\n* This latter function uses a sort of hack (thanks to [Jonatan](http://sccode.org/kymatica), see discussion on sc-users [here](http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/getting-at-an-EventStreamPlayer-s-Pbind-tp7586138p7586148.html)) to get at the arrays inside the patternpairs of the patternproxy inside the 'receiver' inside the stream of the player.   \r\n`z = i.stream.slotAt('receiver');`\r\n\r\n* The point here is that using this technique, one need not maintain administrative data about the patterns themselves -- one only has to remember the players as they are being created.\r\n\r\n`\r\n`\r\nand the meta-point here, beyond me having fun figuring out markdown, is that i would like to make an argument for a less hacky way of legally getting at an EventStreamPlayer's progenitor Pattern.\r\n   \r\n   \r\n   \r\n* [http://soundcloud.com/all-n4tural/constant-blues-acapella-rmx](http://soundcloud.com/all-n4tural/constant-blues-acapella-rmx)\r\n* [http://soundcloud.com/all-n4tural/worldwide-razzledazzle](http://soundcloud.com/all-n4tural/worldwide-razzledazzle)",
   "ancestor_list" : [],
   "author" : "alln4tural",
   "name" : "more fun with patternproxies, feat. a hack to access internals of the EventStreamPlayer"
}
