«Binary Shift Register Sequencer by Dario Lozano-Thornton» by Dario Lozano-Thornton

on 16 Feb'19 22:59 in sequencerbinaryshiftregister

This is a truly wacky patch I wrote 3 years ago and never developed properly. Posting as is, with some operational quirks and poor notes. (link in comments)

This is a triple shift register with a binary counter controlling a switch, made to work as a sequencer.

  • The registers have different speeds, controlled with the bottom three knobs. (tempos could be made to be relational...)
  • Pressing buttons 1-3 add's an "on" into the individual shift register or deletes it.
  • The first column is added together and that output can be seen on the row of buttons above the two sliders. this goes to the left synth. The third column is added together and sent to the right synth.
  • The first slider changes the sequence length
  • The second slider transposes the notes (what if this re-ordered the outputs instead?)
  • The 8 knobs are the 8 possible values sent out
  • There is a high pass so that a low number can be chosen as an off state, creating rests (particularly useful as the zero state gets often outputted by the binary counter)
  • Flip means that row 1 becomes it's inverse every other time, allowing for more complex and longer sequences.

This could be made to control percussion, or lights or solenoids or whatever. I originally wanted to build it electronically as it would be relatively simple (great for eurorack). Messing with the clocking and input stages would be insane.

I'm sharing this to be developed freely, although if anyone makes anything big or commercial it would be lovely to be acknowledged and contacted so I can share it. Some debts to Peter Blasser and Rob Hordijk.

This is not chaotic and does not feed itself back into itself, although it could.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//Dario Lozano-Thornton's Binary Shift Register Sequencer
(
Window.closeAll;
~w2 = Window.new("Binary Register", Rect(400,400,200,320)).front.alwaysOnTop_(true);
~w2.view.decorator = FlowLayout.new(~w2.bounds);
~butt = 3.collect{~w2.view.decorator.nextLine;8.collect{Button(~w2,20@20)}};
~bits = 0!8!3;
~binary_2digit = 8.collect{|i|[i,i.asBinaryString[5..8]]};
~values = 0!8;
~length = 8;
~chosenvalue = 0;
~chosenvalue2 = 0;
~shift_on_v = 1!3;
~tempo = [1,0.7,0.6];
~flip = [0,1];

//show length
~t_loops = 3.collect{|k|
	Task({inf.do{|i|{
		if(~bits[k][i%8]==1,
			{if((i%8)>=~length,{~butt[k][i%8].states = [["",Color.black, Color.black]]},
				{~butt[k][i%8].states = [["",Color.black, Color.red]]})},
			{if((i%8)>=~length,{~butt[k][i%8].states = [["",Color.black, Color.black]]},
				{~butt[k][i%8].states = [["",Color.white]]})})}.defer;
	0.01.wait}}).play};

~w2.view.decorator.nextLine;
//register buttons
~acc = 3.collect{|k|Button(~w2,60@20).states_([[k+1]])
	.action_({if(~bits[k][0].asInt == 0,{~bits[k][0]=1},{~bits[k][0]=0})})};

//shift bits

~shift_register1 = Task{inf.do{~bits[0]=~bits[0].shift(1);~bits[0][0]=~flip@~bits[0][~length-1];~tempo[0].wait}}.play;

~shift_register2 = Task{inf.do{~bits[1]=~bits[1].shift(1);~bits[1][0]=[0,1]@~bits[1][~length-1];~tempo[1].wait}}.play;

~shift_register3 = Task{inf.do{~bits[2]=~bits[2].shift(1);~bits[2][0]=[0,1]@~bits[2][~length-1];~tempo[2].wait}}.play;

~shift_list = [~shift_register1,~shift_register2,~shift_register3];

~outs = 8.collect{Button(~w2,20@20)};
~multiplex = Task({inf.do{
	~binary_2digit.do({|i,k|
		{if(i[1] == (~bits[2][0].asString++~bits[1][0].asString++~bits[0][0].asString),
			{~outs[k].states = [["",Color.black, Color.red]]; ~chosenvalue = k},
			{~outs[k].states = ["",Color.white]})
	}.defer});
	0.01.wait}}
).play;


~knobs = 8.collect({|k|Knob(~w2,20@20).action_({|i|~values[k] = i.value})});
~knobs.do{|v|v.valueAction = 1.0.rand};
3.collect{|k|Button(~w2,60@20)
	.states_([[k.asString++": ON",Color.black, Color.red],[k.asString++": OFF",Color.black, Color.white]])
	.action_({if(~shift_on_v[k] == 1,{~shift_on_v[k] = 0; ~shift_list[k].pause},{~shift_on_v[k] = 1; ~shift_list[k].play})})
};

~outs2 = 8.collect{Button(~w2,20@20)};
~multiplex2 = Task({inf.do{
	~binary_2digit.do({|i,k|
		{if(i[1] == (~bits[2][2].asString++~bits[1][2].asString++~bits[0][2].asString),
			{~outs2[k].states = [["",Color.black, Color.red]]; ~chosenvalue2 = k},
			{~outs2[k].states = ["",Color.white]})
	}.defer});
	0.01.wait}}
).play;

Slider(~w2,190@20)
.action_({|v|~length = v.value.linlin(0,1,3,8).asInt})
.value = 1;

~transpose = 0;
Slider(~w2,190@20)
.action_({|v|~transpose = v.value.linlin(0,1,0,4).asInt})
.value = 0;
~transpose_opt = [1,3/2,2,3,4];

Knob(~w2,40@40)
.action_({|i|~tempo[0] = i.value.linexp(0,1,1,0.03)})
.value = 1-~tempo[0];
Knob(~w2,40@40)
.action_({|i|~tempo[1] = i.value.linexp(0,1,1,0.03)})
.value = 1-~tempo[1];
Knob(~w2,40@40)
.action_({|i|~tempo[2] = i.value.linexp(0,1,1,0.03)})
.value = 1-~tempo[2];

Button(~w2,60@40)
.states_([["FLIP",Color.black, Color.white],["FLIP",Color.black, Color.red]])
.action_({if(~flip == [0,1],{~flip = [1,0]},{~flip = [0,1]})});


Button(~w2,190@20)
.states_([["Clear",Color.black, Color.white]])
.action_({3.do{|i|8.do{|k|~bits[i][k] = 0}}});

//stereo synth, left is being controlled by tempo[1], right by tempo[2], use ultra low frequencies for muting
x = fork{inf.do{play{HPF.ar(SinOsc.ar(~values[~chosenvalue].linlin(0,1,10,600)*~transpose_opt[~transpose],0,0.3),20)*Env.perc(0.01,0.1).kr(2)}; ~tempo[1].wait}};

y = fork{inf.do{play{HPF.ar(SinOsc.ar([0,
	~values[~chosenvalue2].linlin(0,1,10,600)*~transpose_opt[~transpose]],0,0.3),20)*Env.perc(0.01,0.1).kr(2)};~tempo[2].wait}};

~w2.onClose_({3.do{|i|(~t_loops@i).stop};~shift_register1.stop; ~multiplex.stop; ~multiplex2.stop; ~shift_register2.stop; x.stop; y.stop; ~shift_register3.stop;});
)

//make all random
3.do{|i|8.do{|k|~bits[i][k] = 2.rand}};
raw 4065 chars (focus & ctrl+a+c to copy)
reception
comments