«more fun with patternproxies, feat. a hack to access internals of the EventStreamPlayer» by alln4tural
on 25 Oct'12 17:39 inpossibly 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.
This latter function uses a sort of hack (thanks to Jonatan, see discussion on sc-users here) to get at the arrays inside the patternpairs of the patternproxy inside the 'receiver' inside the stream of the player.
z = i.stream.slotAt('receiver');
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.
and 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
// switching to mono cz SinedPink.aiff is boring // two BufRd-based synths, one percussive, one smoother: ( SynthDef(\bufRdperc1, {| out = 0, bufnum = 0, rate=1, inter=2, posfrac = 0.5, dur = 1, amp = 0.9| var widthfrac = (dur/BufDur.ir(bufnum)) * rate; var sig = Splay.ar([ BufRd.ar(1, bufnum, Phasor.ar( 0, (BufRateScale.kr(bufnum) * rate), (posfrac * BufSamples.kr(bufnum)), (posfrac * BufSamples.kr(bufnum)) + (widthfrac * BufSamples.kr(bufnum))), 1, inter) ]); Out.ar(out, sig * EnvGen.kr(Env.perc,1,1,0,dur,2) * amp ) }).add; SynthDef(\bufRdsmooth1, {| out = 0, bufnum = 0, rate=1, inter=2, posfrac = 0.5, dur = 1, amp = 1| var widthfrac = ((dur/2)/BufDur.ir(bufnum)) * rate; var forward = BufRd.ar(1, bufnum, Phasor.ar( 0, (BufRateScale.kr(bufnum) * rate.abs), (posfrac * BufSamples.kr(bufnum)) - (widthfrac * BufSamples.kr(bufnum)), (posfrac * BufSamples.kr(bufnum)) + (widthfrac * BufSamples.kr(bufnum))), 1, inter); var backward = BufRd.ar(1, bufnum, Phasor.ar( 0, (BufRateScale.kr(bufnum) * rate.abs * (-1)), (posfrac * BufSamples.kr(bufnum)) + (widthfrac * BufSamples.kr(bufnum)), (posfrac * BufSamples.kr(bufnum)) - (widthfrac * BufSamples.kr(bufnum))), 1, inter); var sound = BiPanB2.ar(forward,backward,FSinOsc.kr(dur)); sound = sound * EnvGen.kr(Env.sine,1,1,0,dur,2); sound = sound * amp; Out.ar(out, sound); }).add; ) // // two functions that generate Pbinds ( ~make1perc = { |durs, lib| var n = durs.size; Pbind( \bufnum, PatternProxy(Pseq({lib.choose}!n,inf)), \rate, PatternProxy(Pseq([1],inf)), \posfrac, PatternProxy(Pseq({512.rand/512}!n,inf)), \dur, PatternProxy(Pseq(durs,inf)), \amp, PatternProxy(Pseq({(1..3).choose}!n,inf)), \instrument,PatternProxy(Pfunc({ |ev| ("bufRdperc" ++ ev[\bufnum].numChannels) })) ); }; ~make1smooth = { |durs, lib| var n = durs.size; Pbind( \bufnum, PatternProxy(Pseq({lib.choose}!n,inf)), \rate, PatternProxy(Pseq([1],inf)), \posfrac, PatternProxy(Pseq({512.rand/512}!n,inf)), \dur, PatternProxy(Pseq(durs,inf)), \amp, PatternProxy(Pseq({(1..3).choose}!n,inf)), \instrument,PatternProxy(Pfunc({ |ev| ("bufRdsmooth" ++ ev[\bufnum].numChannels) })) ); }; // // // the function with the hack to get at, and modify while running, the internals of the patterns ~frac = { |n = 1| ~players.do{ |i| var z = i.stream.slotAt('receiver'); // the hack. it wd be nice to have legal method for this z.patternpairs.at(z.patternpairs.indexOf('posfrac') + 1).source = Pseq({512.rand/512}!n,inf) } }; ) // // // // fun things to execute at runtime // /* ~buffers is an array of mono Buffers. if you don't have any, you can do ~buffers = [Buffer.read(s, Platform.resourceDir ++ "/sounds/a11wlk01.wav")]; */ [1/8, 1/4, 1/2].do{|i| ~players = ~players.add((~make1perc.([i], [~buffers.choose])).play)} 1.do{~players = ~players.add((~make1smooth.([1], [~buffers.choose])).play)} ~frac.(); ~frac.(x = 1); ~frac.(x = x*2); ~frac.(x = x+2); ~frac.(x.postln); ~players.pop.stop;
interesting technique and fun sound ) but code seems to work with stereo buffers only, so a11wlk01 is not an option - there is stereo SinedPink.aiff in Platform.resourceDir++'/sounds' p.s. need to reset "~players = [];" on re-run
ah, thanks -- at home i have mono versions of the synthdefs, sorry. i didnt want to add those, too, it's already too complicated.
i do ~players.pop.stop to kill them one by one.