‹ Annette n-bit Computers ›

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};
  };
};
)

‹ Annette n-bit Computers ›