‹ Annetten-bit Computers ›

2-bit Computer Sonification

2010-11-26 03:57:49 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};
    };
};
)
‹ Annetten-bit Computers ›