Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Otomata SuperCollider prototype
- //http://www.batu.in/otomata
- //Batuhan Bozkurt 2010
- //Boot server first and execute Otomata.new to run.
- Otomata
- {
- var width, <numRows;
- var <win, <view;
- var cells;
- var <cellWidth;
- var isPlaying;
- var thread;
- var routine;
- var <>speed;
- var <>pitches;
- *new
- {|argWidth = 500, argNumRows = 9|
- ^super.new.init(argWidth, argNumRows);
- }
- init
- {|argWidth, argNumRows|
- width = argWidth;
- numRows = argNumRows;
- cellWidth = width / numRows;
- isPlaying = false;
- speed = 0.2;
- cells = List.new;
- pitches = [50, 57, 58, 60, 62, 64, 65, 69, 72];
- win = Window.new("Otomata", Rect(300, 300, width, width));
- win.onClose_({ if(isPlaying, { thread.stop; }); });
- view = UserView(win, win.view.bounds).background_(Color.black);
- view.mouseDownAction =
- {|...args|
- if(isPlaying == false,
- {
- if(args[4] == 0, //left click
- {
- cells.add(OtomataCell.new(this, (args[1] / cellWidth).floor, (args[2] / cellWidth).floor));
- });
- });
- win.refresh;
- };
- win.view.keyDownAction =
- {|...args|
- if(args[1] == $ , //if space pressed
- {
- if(isPlaying == false,
- {
- isPlaying = true;
- thread = routine.fork;
- },
- {
- thread.stop;
- isPlaying = false;
- });
- });
- };
- routine =
- {
- loop
- ({
- cells.do
- ({|srcCell|
- cells.do
- ({|targetCell|
- if(srcCell != targetCell,
- {
- if((srcCell.curRow == targetCell.curRow) and: { srcCell.curCol == targetCell.curCol },
- {
- { srcCell.toNextState(); }.defer;
- Synth(\cwMeet);
- "two (or more) cells collided at gridX: %, gridY: %.".format(srcCell.curCol, srcCell.curRow).postln;
- });
- });
- });
- });
- cells.do
- ({|item|
- { item.advance(); }.defer;
- });
- speed.wait;
- });
- };
- SynthDef(\Otomatar,
- {
- arg pan = 0, freq = 100;
- var snd;
- snd = LPF.ar(WhiteNoise.ar(0.25), freq) * Decay.ar(Impulse.ar(0), 0.1);
- DetectSilence.ar(snd, doneAction: 2);
- Out.ar(0, Pan2.ar(snd, pan));
- }).add;
- SynthDef(\cwMeet,
- {
- var snd;
- snd = Impulse.ar(0);
- DetectSilence.ar(snd, doneAction: 2);
- Out.ar(0, snd.dup);
- }).add;
- SynthDef(\cwHang,
- {
- arg pan = 0, note = 50;
- var snd;
- var trig = Impulse.ar(0);
- snd = SinOsc.ar(note.midicps * Rand(0.99, 1.01), 0, 0.5) * Decay.ar(trig, Rand(1.4, 1.8) * 1.5);
- snd = snd + (SinOsc.ar(note.midicps * 2 * Rand(0.999, 1.001), 0, 0.25) * Decay.ar(trig, Rand(0.8, 1.2)));
- snd = snd + (SinOsc.ar(note.midicps * 3 * Rand(0.999, 1.001), 0, 0.1) * Decay.ar(trig, Rand(0.5, 0.8)));
- snd = snd + (LPF.ar(WhiteNoise.ar(0.5), note.midicps * 2.5) * Decay.ar(trig, Rand(0.05, 0.12)));
- DetectSilence.ar(snd, doneAction: 2);
- Out.ar(0, Pan2.ar(snd, pan));
- }).add;
- win.front;
- }
- }
- OtomataCell
- {
- var curState;
- var parent;
- var <curCol, <curRow;
- var view;
- *new
- {|argParent, argCol, argRow|
- ^super.new.init(argParent, argCol, argRow);
- }
- init
- {|argParent, argCol, argRow|
- curState = 0;
- parent = argParent;
- curCol = argCol.asInt;
- curRow = argRow.asInt;
- view =
- UserView
- (
- parent.win,
- Rect
- (
- curCol * parent.cellWidth,
- curRow * parent.cellWidth,
- parent.cellWidth - 1,
- parent.cellWidth - 1
- )
- ).background_(this.stateColor().postln);
- view.mouseDownAction_
- ({|...args|
- if(args[4] == 0, //left click
- {
- this.toNextState();
- });
- });
- }
- toNextState
- {
- curState = ((curState + 1) % 4).asInt;
- view.background_(this.stateColor());
- }
- stateColor
- {
- curState.switch
- (
- 0, { ^Color.red; },
- 1, { ^Color.green; },
- 2, { ^Color.blue; },
- 3, { ^Color.cyan; }
- );
- }
- advance
- {
- curState.switch
- (
- 0,
- {
- if(curRow == 0, { curState = 2; });
- curRow = (curRow - 1).fold(0, parent.numRows - 1);
- if(curRow == 0, { this.doBound(); });
- },
- 1,
- {
- if(curCol == (parent.numRows - 1), { curState = 3; });
- curCol = (curCol + 1).fold(0, parent.numRows - 1);
- if(curCol == (parent.numRows - 1), { this.doBound(); });
- },
- 2,
- {
- if(curRow == (parent.numRows - 1), { curState = 0; });
- curRow = (curRow + 1).fold(0, parent.numRows - 1);
- if(curRow == (parent.numRows - 1), { this.doBound(); });
- },
- 3,
- {
- if(curCol == 0, { curState = 1; });
- curCol = (curCol - 1).fold(0, parent.numRows - 1);
- if(curCol == 0, { this.doBound(); });
- }
- );
- this.updateView(curCol, curRow);
- }
- updateView
- {
- view.bounds =
- Rect
- (
- curCol * parent.cellWidth,
- curRow * parent.cellWidth,
- parent.cellWidth - 1,
- parent.cellWidth - 1
- );
- view.background = this.stateColor();
- }
- doBound
- {
- "triggering sound at gridX: %, gridY: %".format(curCol, curRow).postln;
- if((curState == 0) or: { curState == 2; },
- {
- Synth(\cwHang, [\pan, (curCol / parent.numRows) * 2 - 1, \note, parent.pitches[curCol]]);
- },
- {
- Synth(\cwHang, [\pan, (curCol / parent.numRows) * 2 - 1, \note, parent.pitches[parent.numRows - 1 - curRow]]);
- });
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement