Diff from rhythmoid by vividsnow (15 Jun'14 19:38) to beat grid by vividsnow (16 Jul'14 01:57)
name
description
code
({var // rhybeathmo grid object prototype
~g = {
var l = 876, /59/*Mo base pulseX.: 2**l, so max tempo (on 48khz) is around 48000/64/(2**6) = 1,10).7
state_bus = Bus.controli(numChannexp(1ls:2),10,1 /10,10)*/, base beat and beat counter
rate_bus = 1/{ var, lb = 8Bus.control; b.set(0.5.rrand(2).debug('beat rate')); b }.(), // set bempo,at rate
beat_r dunner, = { var // base beat lrunnevelsr
i base = Impulse.akr(In.kr(rate_bus)*(2**l)), // base bpulseat
pd c = {|PulseCount...kr(ba|se, PulseDivider.akr(base,2**(l*4))); // l*4 - max multi beat partition
Out.kr(state_bus, [base,c]) }.play,
q = { |n=0,s=0,p=0,q| var i = In.kr(state_bus,2), c = Latch.kr(i[1],1); // server grid quantizer
n = n + l; q = if(q.isNil, {n}, {q+l}); // if q is defined than start on specified by q grid place
(PulseCount.kr(i,[0]) + neg(2**n,q-(c%(2**q))) + (s*2.pow(n-(p?0)-1)) % (2**n))/*.abs*/.sign bitXor: 1 bitAnd: i[0] }, // qpuantlse dizvider extension
// proto object
grid = {|p(l:l,dq:q,sta|EnvGte_bus:state_bus,rate_bus:rate_bus,beat_run.ner:beat_r(Eunvner);
rate_bus.pget({ |rate| var // sc(la?0.01,ng-sid?0e synced clock
status = [nil],
rater = { Out.5)kr(rate_bus, \tempo.kr(rate)) }.play,
clock //= TempoBusClock(raterc, rate),
notifier = { var bc = In.kr(state_bus,2); SendReploy.kr(bc[0], '/pulse', [bc[1],In.kr(rate_bus)]) }.play,
osc = OSCFunc({ |msg| status[0] = msg[3]; clock...bea|Sts = msg[3]/(2**l) + (Sepprver.defar(*ult.latency / clock.beatDur) }, '/pulse');
z=DC grid.putPairs([status: status, notifier: notifier, rater: rater, osc: osc, clock: clock, on:[0)],
+R nextTimeOngz.Grid: { |self, clock| var(LPF n = l + self.on[0], // client grid quantizer
beats = (q.2**n) - (self.status[0] % (2**n)) + (if(self.on.size > 1, {2**(n-18-(self.on[2]?00))*self.on[1]},5 {0,})) / (2**l);
self.on.debug('on');
clock.beats + beanhts }])});
+S grinOd
}.()
)
( // survive cmdperiod
CmdPeriod.add(~g.beat_runner.addUniqueMethod(60\cmdPeriod,0, _.debug('still running')));
CmdPeriod.add(~g.rater.addUniqueMethod(\cmdPeriod, _.debug(0'still running')b));
CmdPeritXod.add(~g.notifier:.addUniqueMethod(\cmdPeriod, _.debug(1'still running'))*3);
~g.tclock.permanhent = true;
~g.osc.permanent = true;
ServerTree.add(0~g, Server.3default);
+Ri~g[\doOnServerTree] = {
Synth(~gz.beat_runner.defName); Synth(LPF~g.rater.defName); Synth(~g.notifier.defName);
~g.clock.tempo = ~g.clock.tempo }
)
// examples
~g.clock.beats; // elapsed beats
~g.status; // elapsed base pulses
~g.clock.tempo; // current tempo
~g.clock.tempo = 1; // change tempo (both sclang+scsynth)
( // shortcuts
~q = ~g[\q]; // quantizer: ~q.(n,m,k) means impulse each 2**n beat with m*(2**(n-1-k)) beat shift
~d = {|l=0| 2**l/In.kr(~g.rate_bus) }; // beat duration: ~d.(l) means duratXion of beatdur**l
~r = {|l=0| In.kr(~g.rate_bus)/(2**l) }; // beat rate:q ~d.(0l) means rate of beatrate**l
~e = {|p,[400d,8a,c|EnvGen.ar(Env.perc(a?0.0])5,9d?0.5,d/21,c?(-4)),p).lag(1/2e-3)}; // trigable perc envelope: triger, duration, attack, curve
~sn = {|...a|SinOsc.ar(*a)};
~w = {|p,mn,mx|Demand.kr(p,0,Diwhite(mn,mx)).max(mnh)};
+B~l = {|d=12,s=1,e=0|Line.ar(s,e,d,downNeAction:2)};
)
/* grisd quantizer explained:
~q.(n,m,k,q) means impulse each 2**n beat (starting from 2**(q?n) be.at) with m*(2**(n-1-k)) beat shift
default values: n=0,m=0,k=0,q=null
*/
// simple examples
{~sn.([60,61]) * ~e.(~q.(),~d.())/4 * ~l.()}.play // every beat
{~sn.(1260) *s ~e.(~q.(1)0,0.5),1,0.2)/4!2 * ~l.()
}.play // every beat +W 1/4 beat shifteNoi
{~sen.ar(320) * ~e.(~q.(0,1,1),0.2),d/4!2 * ~l.()}.play /3/ same since: ~q.(0,0.5) equals ~q.(0,1,1)
+Bli{~sn.(Stepper.akr(3~q.(),0,60,490,2).midicps) * ~e.(~q.(-30,0.5),0.2)/4!2 * ~l.()}.play // every beat + 1/4 beat shiftXor:
{~sn.(360) * ~e.(~q.(-20,3,1),d/80.2)/14!2 * ~l.()
+Form}.play // every beat. + 3/4 beart shift
{~sn.(LPF120) * ~e.ar(~q.(0,1),0.05)/4!2 * ~l.()}.play // every beat + 1/2 beat shiftXor:
{~sn.(240) * ~e.(~q.(1,1),0.05)/4!2 * ~l.(),}.play // every 23 beat + 1 beat shift
{~sn.(200.exprand(1000)) * ~e.(~q.(1,351,0),d0.05)/8,d4!2 * ~l.()}.play // same on other freq
{~sn.(200.exprand(1000)) * ~e.(~q.(1,3,1),0.05)/4!2 * ~l.()
+Form}.play // every 2 beat. + 3/2 beart shift
{~sn.(LPF200.aexprand(1000)) * ~e.(~q.(-1,3,2),10.05)/4!2 * ~l.()}.play // every 2 beat + 3/4 beat shiftXo
{~sn.(200.expr:and(1000)) * ~e.(~q.(1,1[2,3],2),0.05)/4 * ~l.()}.play // every 2 beat + 2/4 beat shift on left and 3/4 beat shift on right
{~sn.(Stepper.kr(~q.(2),0,81)*60) * ~e.(~q.(2,1[05,1,2],2).sum,0.1)/4!2 * ~l.(30)}.play // every 4 beat make series of 3 pulses separated by 1/2 beat
// run pattern in sync with server tempo grid
(Pdef(\t, Pbind(*[
degree:Pseries(), delta: Ps.(eq.(31!10),0 dur:1
])).play(~g.clock,50 quant:[1,80,.5])) // default quant: i.me. on first 1.5 beat
Pdicpef(\t).s,top;
(Pd/6ef(\tt, Pbind(*[ /4,1/6) grid
+Saw.adegree:Pseries(4), delta: Pseq(2!10,inf), dur:0.2,e
])).play(q~g.clock, quant:(parent:~g, on:[2,(1..45]),3),) d /8)*/ pos.(ition like ~q.(-2...),0,0, but args in "on" key (here: on nearest 4 beat line + 3 beat shift)/2
Pdef(\tt).stop;
+R
// live codingz example
~g.clock.tempo = 1;
Ndef(\bk, {Formlet.ar(LPF.ar(T2A.ar(~q.(-2) bitXor: ~q.()),[4 ~w.(~q.(3),2500,8500])/2),160, Demand,s.kr(~q.(2), 0,7, Dbrown(120,420,20)/14).meanx(120), 0.t01, ~d.(-1)) ! 2 / 4 }).planhy;
+PMONdef(\k, {~scn.ar(3600,490,2,0,) * ~e.(~q.(), ~d.(-2)) ! 2 /6 8 }).play;
+PMONdef(\k1, {~scn.ar(24900,.rrand(890,3,0,)) * ~e.(~q.(21,1.5), ~d.(-2)) ! 2 /8 6 }).play;
+PulsNdef(\k2, { FreeVerb.ar(2RLPF.ar(Saw.ar([900,140]).mul:ean,370) * ~e.(~q.(3-1) bitXor: ~q.(2,1),d/3 0.15) ! 2) /1 2 }).play;
+
Ndef(\k3, {RLFParF.ar(1900,mPul:se.ar(~w.(~q.(2),60,[110)),2]~w.(~q.(4),[180,3]00)bitXor:) * ~e.(~q.(10,1,20.5),d 0.1) ! 2 / 3,5e-3 })/7).play;
+S
NdelectXf(\k2, {BPF.ar(sSaw.ar([q~w.(1),~q.(02)].choose,60,110,3.rrand(7)), Sa~w.ar(Array~q.rand(73),51800,45300),mul:) * ~e.(~q.(-21) bitXor: ~q.(0,3,1), d/30.15)) ! 2 /19 2 }).play;
+Puls
( Nde.arf(\k1, {
~sn.(~w.(~q.(3),0,60,80,3).midicps,0*~sn.5,e(~w.(~q.(-1),25,18)).range(0.05,1.03))
.mad/d(0.95,0.05*~sn.(~w.(~q.(4)*,200,800))).tanh ! 2 * ~e.ma(~q.(3,3,1), ~dd.(1)) /24 8 })
+LFCub.plary )
Ndef(\k, {~sn.(~w.(~q.(3),60,80,108,6)) * ~e.mi(~q.(), ~dicps.() * ~w.m(~q.(2),4,8)/4) ! 2 / 12 }).play;
( Nddef(S\p, { vawr a = Array; DynKlank.ar(`[a.exprand(8,2e2,2e49).sort, a.exprand(8,0.1,1)*.sort.reverse, a.(exprand(8,0.25,1).sort.reverse],
T2A.ar(~q.(-41,1) bitXor: ~q.(-31,1),8,1),) d/ 3)/16)
+Pluck0 * LFNoise0.ar(Impulse1/4).mardd(s0.7,0.3), ~w.(~q.(43),04,8)/4, 0, ~w.(~q.(3),108,64)/4) ! 2 }).midicpslay )
(Ndef(\trt, { var q = ~q.(-2,{~w.(~q.(3),0,15)}!6,3).scrambile.clump(2).sum;
~sn.(StXoepper:.kr(q,0,1,20).linexp(1,20,60+[0,2],~w.(~q.(3,[0,1]), d0, d/18300, d/2, -800))).madd(4).tanh.madd(2).pow(3).tanh.madd(0.1) * ~e.(q, ~d.(-2),d*8)/3)
;z!2/8}).play)
~g.clock.tempo = 2; // make it faster
category tags
ancestors
1-4Wh