Advertisement
Guest User

Otomata SuperCollider prototype

a guest
Apr 10th, 2011
592
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //Otomata SuperCollider prototype
  2. //http://www.batu.in/otomata
  3. //Batuhan Bozkurt 2010
  4. //Boot server first and execute Otomata.new to run.
  5.  
  6. Otomata
  7. {
  8.     var width, <numRows;
  9.     var <win, <view;
  10.     var cells;
  11.     var <cellWidth;
  12.     var isPlaying;
  13.     var thread;
  14.     var routine;
  15.     var <>speed;
  16.     var <>pitches;
  17.        
  18.     *new
  19.     {|argWidth = 500, argNumRows = 9|
  20.        
  21.         ^super.new.init(argWidth, argNumRows);
  22.     }
  23.    
  24.     init
  25.     {|argWidth, argNumRows|
  26.        
  27.         width = argWidth;
  28.         numRows = argNumRows;
  29.         cellWidth = width / numRows;
  30.         isPlaying = false;
  31.         speed = 0.2;
  32.        
  33.         cells = List.new;
  34.         pitches = [50, 57, 58, 60, 62, 64, 65, 69, 72];
  35.         win = Window.new("Otomata", Rect(300, 300, width, width));
  36.         win.onClose_({ if(isPlaying, { thread.stop; }); });
  37.         view = UserView(win, win.view.bounds).background_(Color.black);
  38.        
  39.         view.mouseDownAction =
  40.             {|...args|
  41.                
  42.                 if(isPlaying == false,
  43.                 {
  44.                     if(args[4] == 0, //left click
  45.                     {
  46.                         cells.add(OtomataCell.new(this, (args[1] / cellWidth).floor, (args[2] / cellWidth).floor));
  47.                     });
  48.                 });
  49.            
  50.                 win.refresh;
  51.             };
  52.            
  53.         win.view.keyDownAction =
  54.             {|...args|
  55.                
  56.                 if(args[1] == $ , //if space pressed
  57.                 {
  58.                     if(isPlaying == false,
  59.                     {
  60.                         isPlaying = true;
  61.                         thread = routine.fork;
  62.                     },
  63.                     {
  64.                         thread.stop;
  65.                         isPlaying = false;
  66.                     });
  67.                 });
  68.             };
  69.            
  70.         routine =
  71.             {
  72.                 loop
  73.                 ({
  74.                     cells.do
  75.                     ({|srcCell|
  76.                        
  77.                         cells.do
  78.                         ({|targetCell|
  79.                            
  80.                             if(srcCell != targetCell,
  81.                             {
  82.                                 if((srcCell.curRow == targetCell.curRow) and: { srcCell.curCol == targetCell.curCol },
  83.                                 {
  84.                                     { srcCell.toNextState(); }.defer;
  85.                                     Synth(\cwMeet);
  86.                                     "two (or more) cells collided at gridX: %, gridY: %.".format(srcCell.curCol, srcCell.curRow).postln;
  87.                                 });
  88.                             });
  89.                         });
  90.                     });
  91.                    
  92.                     cells.do
  93.                     ({|item|
  94.                        
  95.                         { item.advance(); }.defer;
  96.                     });
  97.                    
  98.                     speed.wait;
  99.                 });
  100.             };
  101.            
  102.  
  103.         SynthDef(\Otomatar,
  104.         {
  105.             arg pan = 0, freq = 100;
  106.             var snd;
  107.            
  108.             snd = LPF.ar(WhiteNoise.ar(0.25), freq) * Decay.ar(Impulse.ar(0), 0.1);
  109.             DetectSilence.ar(snd, doneAction: 2);
  110.             Out.ar(0, Pan2.ar(snd, pan));
  111.         }).add;
  112.        
  113.         SynthDef(\cwMeet,
  114.         {
  115.             var snd;
  116.            
  117.             snd = Impulse.ar(0);
  118.             DetectSilence.ar(snd, doneAction: 2);
  119.             Out.ar(0, snd.dup);
  120.         }).add;
  121.        
  122.         SynthDef(\cwHang,
  123.         {
  124.             arg pan = 0, note = 50;
  125.             var snd;
  126.             var trig = Impulse.ar(0);
  127.             snd = SinOsc.ar(note.midicps * Rand(0.99, 1.01), 0, 0.5) * Decay.ar(trig, Rand(1.4, 1.8) * 1.5);
  128.             snd = snd + (SinOsc.ar(note.midicps * 2 * Rand(0.999, 1.001), 0, 0.25) * Decay.ar(trig, Rand(0.8, 1.2)));
  129.             snd = snd + (SinOsc.ar(note.midicps * 3 * Rand(0.999, 1.001), 0, 0.1) * Decay.ar(trig, Rand(0.5, 0.8)));
  130.             snd = snd + (LPF.ar(WhiteNoise.ar(0.5), note.midicps * 2.5) * Decay.ar(trig, Rand(0.05, 0.12)));
  131.             DetectSilence.ar(snd, doneAction: 2);
  132.             Out.ar(0, Pan2.ar(snd, pan));
  133.         }).add;
  134.            
  135.         win.front;
  136.     }
  137. }
  138.  
  139. OtomataCell
  140. {
  141.     var curState;
  142.     var parent;
  143.     var <curCol, <curRow;
  144.     var view;
  145.    
  146.     *new
  147.     {|argParent, argCol, argRow|
  148.        
  149.         ^super.new.init(argParent, argCol, argRow);
  150.     }
  151.    
  152.     init
  153.     {|argParent, argCol, argRow|
  154.        
  155.         curState = 0;
  156.         parent = argParent;
  157.         curCol = argCol.asInt;
  158.         curRow = argRow.asInt;
  159.  
  160.         view =
  161.             UserView
  162.             (
  163.                 parent.win,
  164.                 Rect
  165.                 (
  166.                     curCol * parent.cellWidth,
  167.                     curRow * parent.cellWidth,
  168.                     parent.cellWidth - 1,
  169.                     parent.cellWidth - 1
  170.                 )
  171.             ).background_(this.stateColor().postln);
  172.        
  173.         view.mouseDownAction_
  174.         ({|...args|
  175.            
  176.             if(args[4] == 0, //left click
  177.             {
  178.                 this.toNextState();
  179.                
  180.             });
  181.         });
  182.     }
  183.    
  184.     toNextState
  185.     {
  186.         curState = ((curState + 1) % 4).asInt;
  187.         view.background_(this.stateColor());
  188.     }
  189.        
  190.     stateColor
  191.     {
  192.         curState.switch
  193.         (
  194.             0, { ^Color.red; },
  195.             1, { ^Color.green; },
  196.             2, { ^Color.blue; },
  197.             3, { ^Color.cyan; }
  198.         );
  199.     }
  200.    
  201.     advance
  202.     {
  203.         curState.switch
  204.         (
  205.             0,
  206.             {
  207.                 if(curRow == 0, { curState = 2; });
  208.                 curRow = (curRow - 1).fold(0, parent.numRows - 1);
  209.                 if(curRow == 0, { this.doBound(); });
  210.             },
  211.             1,
  212.             {
  213.                 if(curCol == (parent.numRows - 1), { curState = 3; });
  214.                 curCol = (curCol + 1).fold(0, parent.numRows - 1);
  215.                 if(curCol == (parent.numRows - 1), { this.doBound(); });
  216.             },
  217.             2,
  218.             {
  219.                 if(curRow == (parent.numRows - 1), { curState = 0; });
  220.                 curRow = (curRow + 1).fold(0, parent.numRows - 1);
  221.                 if(curRow == (parent.numRows - 1), { this.doBound(); });
  222.             },
  223.             3,
  224.             {
  225.                 if(curCol == 0, { curState = 1; });
  226.                 curCol = (curCol - 1).fold(0, parent.numRows - 1);
  227.                 if(curCol == 0, { this.doBound(); });
  228.             }
  229.         );
  230.        
  231.         this.updateView(curCol, curRow);
  232.     }
  233.    
  234.     updateView
  235.     {      
  236.         view.bounds =
  237.             Rect
  238.                 (
  239.                     curCol * parent.cellWidth,
  240.                     curRow * parent.cellWidth,
  241.                     parent.cellWidth - 1,
  242.                     parent.cellWidth - 1
  243.                 );
  244.        
  245.         view.background = this.stateColor();
  246.    
  247.     }
  248.    
  249.     doBound
  250.     {
  251.         "triggering sound at gridX: %, gridY: %".format(curCol, curRow).postln;
  252.        
  253.         if((curState == 0) or: { curState == 2; },
  254.         {
  255.             Synth(\cwHang, [\pan, (curCol / parent.numRows) * 2 - 1, \note, parent.pitches[curCol]]);
  256.         },
  257.         {
  258.             Synth(\cwHang, [\pan, (curCol / parent.numRows) * 2 - 1, \note, parent.pitches[parent.numRows - 1 - curRow]]);
  259.         });
  260.     }
  261. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement