Linear Feedback Shift Register
2014-09-27 20:16
supercollider
clean-up: #35
Over a year ago I was playing with LFSR to generate pseudo-random noise. Below I cleaned up and published the results.
With inspiration from Sebastian Tomczak's lfsr-in-maxmsp and this video.
//4-bit Fibonacci LFSR
//https://en.wikipedia.org/wiki/Linear_feedback_shift_register
(
b= 2r1000; //seed
a= [];
15.do{
a= a++b.asBinaryDigits(4);
b= (b>>1)|((b&1).bitXor(b&2>>1)<<3);
b.postln;
};
"";
)
s.boot
c= Buffer.loadCollection(s, a)
c.plot
{PlayBuf.ar(1, c, MouseX.kr(0, 1), loop:1)!2}.play
//4-bit Fibonacci LFSR with local in/out
(
a= {|rate= 4, iseed= 2r1000|
var b, trig;
var in= LocalIn.kr(1, iseed);
trig= Impulse.kr(rate);
b= Latch.kr(in, trig); //read
b= (b>>1)|((b&1).bitXor(b&2>>1)<<3); //modify
LocalOut.kr(b);
b.poll(trig);
DC.ar(0);
}.play;
)
a.set(\rate, 30)
a.free
//4-bit Fibonacci LFSR as single sample feedback with Dbufrd/Dbufwr
(
a= {|rate= 4, iseed= 2r1000|
var b, trig;
var buf= LocalBuf(1);
buf.set(iseed);
trig= Impulse.ar(rate);
b= Demand.ar(trig, 0, Dbufrd(buf)); //read
b= (b>>1)|((b&1).bitXor(b&2>>1)<<3); //modify
Demand.ar(trig, 0, Dbufwr(b, buf)); //write
b.poll(trig);
DC.ar(0);
}.play;
)
a.set(\rate, 30)
a.free
//LFSR sound example (not sure this is correct but sounds ok)
(
a= {|rate= 400, iseed= 2r1000, tap1= 1, tap2= 3, tap3= 5, length= 16|
var l, b, trig, o;
var buf= LocalBuf(1);
buf.set(iseed);
trig= Impulse.ar(rate);
l= Demand.ar(trig, 0, Dbufrd(buf)); //read
b= l.bitXor(l>>tap1).bitXor(l>>tap2).bitXor(l>>tap3)&1; //modify
l= (l>>1)|(b<<15); //lfsr
Demand.ar(trig, 0, Dbufwr(l, buf)); //write
o= PulseCount.ar(Impulse.ar(rate*length), trig); //bits
l>>o&1!2; //output
}.play;
)
a.set(\rate, 300)
a.set(\rate, 100)
a.set(\length, 3)
a.set(\length, 14)
a.set(\tap1, 14.rand)
a.set(\tap2, 14.rand)
a.set(\tap3, 14.rand)
a.set(\length, 32)
a.set(\rate, 1000)
a.free
//LFSR sound with GUI (not sure this is correct but sounds ok)
(
var w, a;
w= Window("lfsr", Rect(100, 100, 520, 200)).front;
Slider(w, Rect(10, 10, 500, 25)).action_({|view| a.set(\rate, view.value*2000)}).value= 400/2000;
Slider(w, Rect(10, 40, 500, 25)).action_({|view| a.set(\length, view.value*32)}).value= 16/32;
a= {|rate= 400, iseed= 2r1000, tap1= 1, tap2= 3, tap3= 5, length= 16|
var l, b, trig, o;
var buf= LocalBuf(1);
buf.set(iseed);
trig= Impulse.ar(rate);
l= Demand.ar(trig, 0, Dbufrd(buf)); //read
b= l.bitXor(l>>tap1).bitXor(l>>tap2).bitXor(l>>tap3)&1; //modify
l= (l>>1)|(b<<15); //lfsr
Demand.ar(trig, 0, Dbufwr(l, buf)); //write
o= PulseCount.ar(Impulse.ar(rate*length), trig); //bits
l>>o&1!2; //output
}.play;
CmdPeriod.doOnce({w.close});
)