sclang: array primitives - respect mutability when changing object.
[supercollider.git] / examples / research_and_tools / ASA.scd
blobcd40bb1f13661227ff8dc242f4c7655a32722139
1 /*
2 Two Auditory Scene Analysis experiences 
3 as proposed by Bregman, Auditory Scene Analysis, MIT Press, 1990
5 1. Streaming: if rate of presentation and 
6 frequency gap between the two series of sinusoidal tones are varied, 
7  one or two stream(s) appear(s).
9 2. Miniature ASA Problem: varying frequency distance of A and C with respect to B, and attack time of C, two groupings are possible: 
10 (A+B)/C: a two note melody with a low tone (parallel)
11 A(B+C): a simple tone and a complex tone (sequence)
13 (andrea valle)
18 // start server
19 s = Server.local.boot;
26 Streaming
30 var r1, r2;
31 var rateSlide, deltaSlide, volumeSlide;
32 var pauseButton1, pauseButton2, recButton; 
33 var volume1 = 1.0, volume2 = 1.0;
34 var base = 500;
35 var synth1, synth2;
36 var fileName, index = 1;
42 // Two analogous synthDefs
45 SynthDef("sine1",{ arg out=0, freq=440, dur=1.0, mul=0.5;
46         var env;
47         env = Env.new([0, 1,1,0,0],[dur*0.05, dur*0.3,dur*0.15,dur*0.5], 'welch');
48         Out.ar(out,
49                 SinOsc.ar(
50                         freq, 
51                         0, mul
52                 ) * EnvGen.kr(env)
53         )
54 }).send(s);
59 SynthDef("sine2",{ arg out=0, freq=440, dur=1.0, mul=0.5;
60         var env;
61         env = Env.new([0,0,1,1,0],[dur*0.5, dur*0.05, dur*0.3,dur*0.15], 'welch');
62         Out.ar(out,
63                 SinOsc.ar(
64                         freq, 
65                         0, mul
66                 ) * EnvGen.kr(env)
67         )
68 }).send(s);
74 // Two analogous routines
76 r1 = Routine.new({
77         inf.do({ arg i; var k;
78                 var arr=[0,0, 1, 0, 2];
79                 synth1 = Synth.new("sine1");
80                 k = arr[i.mod(5)]*100+base;
81                 synth1.set("freq", k);
82                 synth1.set("dur", rateSlide.value);
83                 synth1.set("mul", volumeSlide.value*volume1);
84                 rateSlide.value.wait;
85                 synth1.free;
86                 });
87 });
92 r2 = Routine.new({
93         inf.do({ arg i; var k;
94                 var arr=[1, 0, 3, 1, 2];
95                 synth2 = Synth.new("sine2");
96                 k = arr[i.mod(5)]*100+base+deltaSlide.value;
97                 synth2.set("freq", k);
98                 synth2.set("dur", rateSlide.value);
99                 synth2.set("mul", volumeSlide.value*volume2);
100                 rateSlide.value.wait;
101                 synth2.free;
102         });
108 // GUI stuff
110 w = Window("ASA: Streaming", Rect(20, 400, 440, 150)).front;
111 w.view.decorator = FlowLayout(w.view.bounds);
112 rateSlide = EZSlider(w, 400 @ 20, "DurEach", ControlSpec(0.05, 2.0, \exp, 0.001, 0.01), 
113         {arg ez; ez.value;}, 0.1);
114 deltaSlide = EZSlider(w, 400 @ 20, "Delta", ControlSpec(0, 1000, \lin, 1, 1), 
115         {arg ez; ez.value;}, 500);
116         
117 volumeSlide = EZSlider(w, 400 @ 20, "Volume", ControlSpec(0.0, 1.0, \lin, 0.1, 0.1), 
118         {arg ez; ez.value;}, 0.5);
122 w.view.decorator.nextLine.shift(50, 20);
124         pauseButton1 = Button(w, 110 @ 30);
125         pauseButton1.states = [
126                         ["1 now is active",Color.black,Color.red],
127                         ["1 now is muted",Color.white,Color.black],
128                 ];
129                 
130         pauseButton1.action = { arg state; 
131                         if(state.value == 1, {volume1 = 0; "muted 1".postln});
132                         if(state.value == 0, {volume1 = 1.0; "activated 1".postln}); 
133                 };
134                 
135 w.view.decorator.shift(10, 0);
136                 
138         pauseButton2 = Button(w, 110 @ 30);
139         pauseButton2.states = [
140                         ["2 now is active",Color.black,Color.red],
141                         ["2 now is muted",Color.white,Color.black],
142                 ];
143                 
144         pauseButton2.action = { arg state; 
145                         if(state.value == 1, {volume2 = 0; "muted 2".postln});
146                         if(state.value == 0, {volume2 = 1.0; "activated 2".postln}); 
147                 };
152 w.onClose_({r1.stop; synth1.free; r2.stop; synth2.free;});
154 SystemClock.play(r1);
155 SystemClock.play(r2);
166 The miniature ASA problem
170 var r1, r2, r3;
171 var text;
172 var rateSlide, volumeSlide, freqASlide, freqBSlide, freqCSlide, shiftCSlide;
173 var pauseButton1, pauseButton2, recButton; 
174 var volume1 = 1.0, volume2 = 1.0, volume3 = 1.0;
175 var base = 500;
176 var synth1, synth2, synth3;
177 var fileName, index = 1;
182 // Three analogous synthDefs
185 SynthDef("sineA",{ arg out=0, freq=1000, dur=1.0, mul=0.35;
186         var env;
187         env = Env.new([0, 0,1,1, 0,0],dur*[0.1, 0.0, 0.3, 0, 0.6], 'welch');
188         Out.ar(out,
189                 SinOsc.ar(
190                         freq, 
191                         0, mul
192                 ) * EnvGen.kr(env)
193         )
194 }).send(s);
199 SynthDef("sineB",{ arg out=0, freq=500, dur=1.0, mul=0.35;
200         var env;
201         env = Env.new([0, 0,1,1, 0,0],dur*[0.6, 0.0, 0.3, 0, 0.1], 'welch');
202         Out.ar(out,
203                 SinOsc.ar(
204                         freq, 
205                         0, mul
206                 ) * EnvGen.kr(env)
207         )
208 }).send(s);
213 SynthDef("sineC",{ arg out=0, freq=250, dur=1.0, mul=0.35, shift=0;
214         var env;
215         env = Env.new([0, 0,1,1, 0,0], dur*[0.6+shift, 0.0, 0.3, 0, 0.1+shift], 'welch');
216         Out.ar(out,
217                 SinOsc.ar(
218                         freq, 
219                         0, mul
220                 ) * EnvGen.kr(env)
221         )
222 }).send(s);
224 // Three analogous routines
226 r1 = Routine.new({
227         inf.do({ arg i;
228                 synth1 = Synth.new("sineA");
229                 synth1.set("freq", freqASlide.value);
230                 synth1.set("dur", rateSlide.value);
231                 synth1.set("mul", volumeSlide.value*volume1);
232                 rateSlide.value.wait;
233                 synth1.free;
234         })
240 r2 = Routine.new({
241         inf.do({ arg i; 
242                 synth2 = Synth.new("sineB");
243                 synth2.set("dur", rateSlide.value);
244                 synth2.set("mul", volumeSlide.value*volume2);
245                 rateSlide.value.wait;
246                 synth2.free;
247         })
252 r3 = Routine.new({
253         inf.do({ arg i;
254                 synth3 = Synth.new("sineC");
255                 synth3.set("freq", freqCSlide.value);
256                 synth3.set("dur", rateSlide.value);
257                 synth3.set("mul", volumeSlide.value*volume3);
258                 synth3.set("shift", shiftCSlide.value);
259                 rateSlide.value.wait;
260                 synth3.free;
261         })
266 // GUI stuff
268 w = Window("ASA: Miniature problem", Rect(20, 400, 440, 220));
269 w.front; // make window visible and front window.
270 w.view.decorator = FlowLayout(w.view.bounds);
271 rateSlide = EZSlider(w, 400 @ 20, "DurEach", ControlSpec(0.2, 2.0, \exp, 0.001, 0.01), 
272         {arg ez; ez.value;}, 1.0);
273 freqASlide = EZSlider(w, 400 @ 20, "Freq A", ControlSpec(50, 2000, \exp, 1, 1), 
274         {arg ez; ez.value;}, 1000);
275 w.view.decorator.nextLine.shift(30);
276 text =  TextField(w,Rect(0,0,150,30));
277 text.string = "Freq B = fixed at 500 Hz";
278 text.boxColor_(Color.grey);
279 text.stringColor_(Color.white);
280 w.view.decorator.nextLine;
281 freqCSlide = EZSlider(w, 400 @ 20, "Freq C", ControlSpec(50, 500, \exp, 1, 1), 
282         {arg ez; ez.value;}, 250);      
283 shiftCSlide = EZSlider(w, 400 @ 20, "Shift C", ControlSpec(-0.5, 0.0, \lin, 0.01, 0.01), 
284         {arg ez; ez.value;}, 0.0);              
285 volumeSlide = EZSlider(w, 400 @ 20, "Volume", ControlSpec(0.0, 1.0, \lin, 0.1, 0.1), 
286         {arg ez; ez.value;}, 0.5);
290 w.view.decorator.nextLine.shift(50, 20);
292         pauseButton1 = Button(w, 110 @ 30);
293         pauseButton1.states = [
294                         ["A now is active",Color.black,Color.red],
295                         ["A now is muted",Color.white,Color.black],
296                 ];
297                 
298         pauseButton1.action = { arg state; 
299                         if(state.value == 1, {volume1 = 0; "muted A".postln});
300                         if(state.value == 0, {volume1 = 1.0; "activated A".postln}); 
301                 };
302                 
303 w.view.decorator.shift(10, 0);
304                 
306         pauseButton2 = Button(w, 110 @ 30);
307         pauseButton2.states = [
308                         ["C now is active",Color.black,Color.red],
309                         ["C now is muted",Color.white,Color.black],
310                 ];
311                 
312         pauseButton2.action = { arg state; 
313                         if(state.value == 1, {volume3 = 0; "muted C".postln});
314                         if(state.value == 0, {volume3 = 1.0; "activated C".postln}); 
315                 };
318 w.view.decorator.shift(20, 0);
321 w.onClose_({r1.stop; synth1.free; r2.stop; synth2.free;  r3.stop; synth3.free;});
323 SystemClock.play(r1);
324 SystemClock.play(r2);
325 SystemClock.play(r3);