2-bit Computer Sonification
2010-11-26 03:57
supercollider
clean-up #11:
As a continuation of the n-bit computer story, here are three snippets of SuperCollider code that sonifies all possible programs of a little 2-bit computer emulator. They all map the sound differently. Note that here I let load
and stor
instructions increase the program counter one extra step.
Rendered MP3s for corresponding code is attached below.
//2-bit computer
//sonification #1 - all possible programs 0-255 in order, 16 ticks each
(
s.waitForBoot{
var mem;
var pc= 0; //program counter
var reg= 0; //register
var format= {|x| x.collect{|x| x.asBinaryString(2)}};
var rd= {|x| mem@@x};
var wr= {|x, y| mem.put(x%mem.size, y)};
var snd;
SynthDef(\snd, {|amp= 0, freq= 400, width= 0.5, pan= 0|
var src= LFPulse.ar(freq, 0, width, amp.lag(0, 0.1));
Out.ar(0, Pan2.ar(FreeVerb.ar(src, 0.2, 0.3), pan));
}).add;
s.sync;
snd= Synth(\snd);
Routine.run{
4.do{|m0|
4.do{|m1|
4.do{|m2|
4.do{|m3|
var op, running= true;
mem= [m3, m2, m1, m0]; //reordering here makes slightly different pieces
pc= 0;
reg= 0;
"".postln;
16.do{
if(running, {
op= mem[pc];
snd.set(\amp, 0.7, \freq, op.linexp(0, 3, 120, 1200), \pan, pc/3*2-1, \width, reg/3*0.8+0.1);
switch(op,
2r00, {running= false}, //halt
2r01, {reg= rd.(pc+1); pc= pc+1}, //load next addy into reg
2r10, {reg= reg+1%4}, //incr reg
2r11, {wr.(rd.(pc+1), reg); pc= pc+1} //stor at addy in next byte
);
pc= pc+1%mem.size;
[\pc, pc, \reg, reg, \mem, format.value(mem)].postln;
});
0.01.wait;
snd.set(\amp, 0);
0.001.wait;
};
};};};};
1.wait;
snd.free;
};
};
)
//2-bit computer
//sonification #2 - all possible programs 0-255 in order, maximum 100 ticks
(
s.waitForBoot{
var mem;
var pc= 0; //program counter
var reg= 0; //register
var format= {|x| x.collect{|x| x.asBinaryString(2)}};
var rd= {|x| mem@@x};
var wr= {|x, y| mem.put(x%mem.size, y)};
var snd;
SynthDef(\snd, {|amp= 0, freq= 400, width= 0.5, mod= 0, t_trig= 0, pan= 0|
var env= EnvGen.ar(Env.perc(0.01, 0.1, 1, 0), t_trig);
var src= SinOsc.ar(mod, SinOsc.ar(freq, 0, 2pi*width), amp);
Out.ar(0, Pan2.ar(src*env, pan));
}).add;
s.sync;
snd= Synth(\snd, [\amp, 0.7]);
Routine.run{
var cnt= 0;
4.do{|m0|
4.do{|m1|
4.do{|m2|
4.do{|m3|
var i= 0, op, running= true;
mem= [m0, m1, m2, m3]; //reordering here makes slightly different pieces
pc= 0;
reg= 0;
while({running and:{i<100}}, {
op= mem[pc];
snd.set(\t_trig, 1, \freq, op.linexp(0, 3, 120, 1200), \pan, pc/3*2-1, \width, pc+1, \mod, pc/3);
switch(op,
2r00, {running= false}, //halt
2r01, {reg= rd.(pc+1); pc= pc+1}, //load next addy into reg
2r10, {reg= reg+1%4}, //incr reg
2r11, {wr.(rd.(pc+1), reg); pc= pc+1} //stor at addy in next byte
);
pc= pc+1%mem.size;
i= i+1;
0.008.wait;
});
("program:"+cnt).postln;
cnt= cnt+1;
};};};};
1.wait;
snd.free;
};
};
)
//2-bit computer
//sonification #3 - all possible programs 0-255 in order, 4 voices with freq from memory
(
s.waitForBoot{
var mem;
var pc= 0; //program counter
var reg= 0; //register
var format= {|x| x.collect{|x| x.asBinaryString(2)}};
var rd= {|x| mem@@x};
var wr= {|x, y| mem.put(x%mem.size, y)};
var snds;
SynthDef(\snd, {|amp= 0, freq= 400, width= 0.5, mod= 0, pm= 0, pan= 0|
var src= SinOsc.ar(mod, SinOsc.ar(freq, SinOsc.ar(pm, 0, 2pi), 2pi*width), amp);
Out.ar(0, Pan2.ar(src, pan));
}).add;
s.sync;
snds= {Synth(\snd)}.dup(4);
Routine.run{
var cnt= 0;
4.do{|m0|
4.do{|m1|
4.do{|m2|
4.do{|m3|
var i= 0, op, running= true;
mem= [m3, m2, m1, m0]; //reordering here makes slightly different pieces
pc= 0;
reg= 0;
while({running and:{i<16}}, {
op= mem[pc];
switch(op,
2r00, {running= false}, //halt
2r01, {reg= rd.(pc+1); pc= pc+1}, //load next addy into reg
2r10, {reg= reg+1%4}, //incr reg
2r11, {wr.(rd.(pc+1), reg); pc= pc+1} //stor at addy in next byte
);
pc= pc+1%mem.size;
4.do{|r|
snds[r].set(
\amp, running.binaryValue*0.3,
\freq, mem[r].linexp(0, 3, 300-cnt, 300+cnt),
\pan, r/3*2-1,
\width, op+1,
\mod, reg/2,
\pm, pc+1
);
0.01.wait;
};
i= i+1;
});
("program:"+cnt).postln;
cnt= cnt+1;
};};};};
1.wait;
snds.do{|x| x.free};
};
};
)