(
Server.default = s = Server.internal;

s.waitForBoot({

var
usr1, usr2, usr3, width= 1280, proj= width-(width/16), painel=proj/4, height= width*0.4, theta=0, theta2=0, theta3=0, 
grava1, grava2, toca1, toca2,
ctr1a=0, ctr1=0, ctr2=0, ctr2a=0, ctr3=0, ctr3a=0, ctr4=0, ctr4a=0, ctr5=0, ctr5a=0, ctr6=0, ctr6a=0,
font1=width*0.01, font2=width*0.025,
sp=width*0.02,
texto1,texto2, 
where=0, where1=0, size=0, size1=0, 
ind=0,ind1=0,
trigger1, trigger2, 
bl=0,bll=0, 
buf1, buf2, buf3, buf4,
dec, dec1, vel1 = 300, vel2 = 1200,
controls, button1, button2, button3, loop, trail1=0.02, trail2=0.1,
intensidade1=0.5, intensidade2= 0.5,
oscresp, meter;

//buffer
buf1 = Buffer.alloc(s, 44100 * 1.0, 1);
buf2 = Buffer.alloc(s, 44100 * 1.7, 1);
buf3 = Buffer.alloc(s, 44100 * 1.11, 1);
buf4 = Buffer.alloc(s, 44100 * 1.8, 1);

//sint
//grava
SynthDef(\rec, { arg out = 0, id, bufnum1 = 0, bufnum2 = 1, mic=0, amp=1, in=20;
	var micro, env;
	micro = In.ar(in, 1);
	env = Linen.kr(micro.round(0.15), 2, 0.5, 0.5, doneAction: 0);//limite mínimo para gravar 
	SendTrig.kr(Impulse.kr(60),id,micro);//declaração micros
	RecordBuf.ar(micro*env, bufnum1, 0, 1, 0.95, loop: 1);
	RecordBuf.ar(micro*env, bufnum2, 0, 1, 0.95, loop: 1);	
}).add;
	
//toca
SynthDef(\play, { arg out = 0, bufnum1 = 0, bufnum2 = 1, pan=0, amp=1, gate=1;
	var player1, player2, env;
	player1 = PlayBuf.ar(1,bufnum1, BufRateScale.kr(bufnum1), loop: 1);
	player2 = PlayBuf.ar(1,bufnum2, BufRateScale.kr(bufnum2), loop: 1);
	env = EnvGen.kr(Env.cutoff(1), gate, doneAction:2);
	Out.ar(out, Mix([player1, player2])*env);
}).add;

	

	
s.sync;

// sistema de lag
Routine({
	inf.do{
		ctr1= ctr1-(ctr1-ctr1a*0.07);
		ctr2= ctr2-(ctr2-ctr2a*0.07);
		
		(1/60).wait;
	};
}).play;

//destribuidor do som
OSCresponder(s.addr, \tr, {|t, r, m|
	switch(m[2],
		1, {ctr1a= m[3].abs.round(0.1);},
		2, {ctr2a= m[3].abs.round(0.1);}
	);
}).add;

//visual
w= Window("pasta", Rect(width/32, 800, proj, height), false, false);
usr1= UserView(w, Rect(proj/2, 0, proj/2, height));
usr1.background = Color.black;
usr2= UserView(w, Rect(0, 0, proj/2, height));
usr2.background = Color.white;

//texto a projectar
texto1= [
"a imobilidade t3o horr7vel das coisas,",
"a minha ignorAncia do que fazer com elas.", 
"assim que se nasce j1 5 tarde demais,",
"se mudar ao mesmo tempo que tudo muda, estarei parado:", 
"o tempo n3o passa, segura-nos*", 
"every life is many days, day after day.",
"we walk through ourselves, meeting robbers, ghosts, giants,",
"old men, young men,", 
"wives, widows, brothers-in-love.",
"but always meeting ourselves.",
"in which part of life do we find the truth?", 
"is it the beginning, the middle or the end?",
"or is it all quasi truth?",
"wait five months. molecules all change.",
"i am other i now.",
"morre-se a cada segundo,",
"a vida 5 uma longa despedida,",
"tudo passa mas algo fica, o bom 5 n3o saber o qu6*",
"preservar 5 n3o fazer:",
"que sobre da gente um @ltimo pingo de torneira, ",
"uma @ltima l1grima ferrugenta de algeroz,", 
"uma manchinha a desaparecer t3o depressa no jardim", 
//que 
"quem passar logo 2 tarde pela casa nem sequer repara",
//que 
"algum dia existimos.",
"all my life needed was a sense of some place to go.",
"quis que f9ssemos duas folhas de uma 1rvore,",
"tocando um no outro por um acaso inevit1vel,",
"sem raz3o, sem ter que haver raz3o:",
"everything never always the same different nothing.",
"de repente era velho para o que quer que fosse.",
"can't bring back time.",
"like holding water in your hand*"];

texto2 = [
"beingless beings.",
"dizem que v3o ter um beb5,", 
"mas na realidade o que v3o ter 5 um octogen1rio",
"que se mija e baba todo,",
"cheira mal, 5 cego", 
"e a quem a gota n3o deixa dar um passo.",
"p0em no mundo desgra4ados, ",
"mas a esses n3o os v6em,",
"para que a natureza possa perpetuar-se",
"e a mesma estrumeira prossiga at5 o infinito.",
"we are all born in the same way", 
"but we die in different ways* ",
"custa a crer que cada unidade na montanha dos mortos,",
"conteve, pouco antes, um universo inteiro que a animava,",
"complexo e emocionante,",
"e uma hist8ria @nica, irrepet7vel,",
"feita de mem8ria e projecto,",
"de desejos, estranhamentos,",
"fantasias, medos:",
"uma intriga dentro da intriga,",
"n3o menos misteriosa do que ela.",
"numbers it is.",
"all music when you come to think,",
"extremes meet.",
"death is the highest form of life.",
"morremos todos os dias:",
"5 a morte de um amigo que nos revela", 
"esse lado indiz7vel do morrer,",
"da perda dele em n8s, no perder-se do mundo;",
"5 o mundo demasiado grande a pesar-nos,",
"5 o adeus; ",
"5 quando os olhos se transformam em p1lpebras;",
"a certeza que deixaremos de viver um dia.",
"aqui fico, onde o tempo me deixou.",
"ningu5m 5 quem queria ser,",
"eu queria ser ningu5m*"];

//visual
usr1.drawFunc= {

Pen.smoothing = true;

//trail
	if((usr1.frame%vel1)==1, {
		Pen.fillColor = Color.gray(0, trail1);
		Pen.fillRect(Rect(0, 0, proj/2, height));
		});

//interruptores 
//mic1
	if(ctr1a.round(0.01)==0, 
		{if(ctr1.round(0.01)==0, {if(bl==0, 
								{size= rrand(font1, font2).postln; 
								where=rrand(sp, height-sp).postln; 
								ind = (ind+1).postln;
								dec = 0.5.coin;
								bl=1; "blocked1".postln})})}); 
								
	if(ctr1a.round(0.01)>0.1, 
		{bl=0; "ready1".postln}); 
		
//mic2	
	if(ctr2a.round(0.01)==0, 
		{if(ctr2.round(0.01)==0, {if(bll==0, 
								{size1= rrand(font1, font2).postln; 
								where1=rrand(sp, height-sp).postln; 
								ind1 = (ind1+1).postln;
								dec1 = 0.5.coin;
								bll=1; "blocked2".postln})})}); 
								
	if(ctr2a.round(0.01)>0.1, 
		{bll=0; "ready2".postln}); 

	
if(dec==true, {		
1.do{
	
	Pen.fillColor_(Color.gray(1, ctr1*intensidade1));
	Pen.font_(Font("Times", size));
	Pen.stringLeftJustIn(texto2.at(ind-1%texto2.size)
		.tr($1, 135.asAscii)
		.tr($2, 136.asAscii)
		.tr($3, 139.asAscii)
		.tr($4, 141.asAscii)
		.tr($5, 142.asAscii)
		.tr($6, 144.asAscii)
		.tr($7, 146.asAscii)
		.tr($8, 151.asAscii)
		.tr($9, 153.asAscii)
		.tr($0, 155.asAscii)
		.tr($@, 156.asAscii)
		.tr($*, 201.asAscii)
		.tr($A, 137.asAscii), 
		Rect(sp, where, 0, 0));

	};
}, {	
1.do{

	Pen.fillColor_(Color.gray(1, ctr1*intensidade1));
	Pen.font_(Font("Times", size));
	Pen.stringRightJustIn(texto2.at(ind-1%texto2.size)
		.tr($1, 135.asAscii)
		.tr($2, 136.asAscii)
		.tr($3, 139.asAscii)
		.tr($4, 141.asAscii)
		.tr($5, 142.asAscii)
		.tr($6, 144.asAscii)
		.tr($7, 146.asAscii)
		.tr($8, 151.asAscii)
		.tr($9, 153.asAscii)
		.tr($0, 155.asAscii)
		.tr($@, 156.asAscii)
		.tr($*, 201.asAscii)
		.tr($A, 137.asAscii), 
		Rect(proj/2-sp, where, 0, 0));

	};
});

};

usr2.drawFunc= {
	Pen.smoothing = true;
	
if((usr2.frame%vel2)==1, {
		Pen.fillColor = Color.gray(1, trail2);
		Pen.fillRect(Rect(0, 0, proj/2, height))
		});

if(dec1==true, {		
	1.do{
	
	Pen.fillColor_(Color.gray(0, ctr2*intensidade2));
	Pen.font_(Font("Times", size1));
	Pen.stringLeftJustIn(texto1.at(ind1-1%texto1.size)
		.tr($1, 135.asAscii)
		.tr($2, 136.asAscii)
		.tr($3, 139.asAscii)
		.tr($4, 141.asAscii)
		.tr($5, 142.asAscii)
		.tr($6, 144.asAscii)
		.tr($7, 146.asAscii)
		.tr($8, 151.asAscii)
		.tr($9, 153.asAscii)
		.tr($0, 155.asAscii)
		.tr($@, 156.asAscii)
		.tr($*, 201.asAscii)
		.tr($A, 137.asAscii), 
		Rect(sp, where1, 0, 0));

	};
}, {
	1.do{
	
	Pen.fillColor_(Color.gray(0, ctr2*intensidade2));
	Pen.font_(Font("Times", size1));
	Pen.stringRightJustIn(texto1.at(ind1-1%texto1.size)
		.tr($1, 135.asAscii)
		.tr($2, 136.asAscii)
		.tr($3, 139.asAscii)
		.tr($4, 141.asAscii)
		.tr($5, 142.asAscii)
		.tr($6, 144.asAscii)
		.tr($7, 146.asAscii)
		.tr($8, 151.asAscii)
		.tr($9, 153.asAscii)
		.tr($0, 155.asAscii)
		.tr($@, 156.asAscii)
		.tr($*, 201.asAscii)
		.tr($A, 137.asAscii), 
		Rect(proj/2-sp, where1, 0, 0));
	};
});

};

usr2.clearOnRefresh = false;
usr1.clearOnRefresh = false;

w.front;

meter = AudioMeter.output([20, 21], rect: 1200@0);

t = Routine({while({w.isClosed.not}, { (1/30).wait; usr1.refresh; usr2.refresh;})}).play(AppClock);

//controlos
controls = SCWindow("III.4", Rect(640, 0, 500, 200));
controls.view.background = Color.grey(0.1);

//butões
// 2-toca faixa
button2 = Button(controls, Rect(200, 50, 100, 100))
    .canFocus_(false)
    .states_([
	["play"],
	["stop"]
    ])
    .action_({ arg it;
    var num = it.value;

if(num == 1) 

{
vel1 = 300; trail1=0.02;
vel2 = 1200; trail2=0.1;

//synths
grava1= Synth.tail(s, \rec, [ \id, 1, \in, 21,  \bufnum1, buf1, \bufnum2, buf2]);
grava2= Synth.tail(s, \rec, [\id, 2, \in, 20, \bufnum1, buf3, \bufnum2, buf4]);
toca1= Synth(\play, [\out, 38, \amp, 1, \bufnum1, buf1, \bufnum2, buf2]);
toca2= Synth(\play, [\out, 39, \amp, 1, \bufnum1, buf3, \bufnum2, buf4]);

loop= Task({585.wait; 
//	grava1.set(\amp, 0); grava2.set(\amp, 0);
	5.wait;
	toca1.release(16); toca2.release(16); vel1=4; vel2=10; // apaga o texto no fim
	20.wait;
	grava1.free; 
	grava2.free; 
	meter.quit;
	0.5.wait;
	w.close; 
	controls.close; 
	}).play(AppClock);

};

if(num == 0) 
	{
loop.stop;
grava1.set(\amp, 0); grava2.set(\amp, 0);
toca1.release(16); 
toca2.release(16); 
vel1=3; 
vel2=2;
trail1=1;
trail2=1;
buf1.zero; 
buf2.zero; 
buf3.zero; 
buf4.zero; 
grava1.free; 
grava2.free; 
	}
    });
button2.font_(Font("Lucida Grande", 12));

//butões
// 3-stop
button3 = Button(controls, Rect(350, 50, 100, 100))
    .canFocus_(false)
    .states_([
	["anticipate end"]
    ])
    .action_({ arg it;
    var num = it.value;

if(num == 0) 
	{
		
Task({
	grava1.set(\amp, 0); grava2.set(\amp, 0);
	5.wait;
	toca1.release(16); toca2.release(16); vel1=4; vel2=10; // apaga o texto no fim
	20.wait;
	grava1.free; 
	grava2.free; 
	meter.quit;
	0.5.wait;
	w.close;
	controls.close;
	}).play(AppClock);

	};
	
    });
button3.font_(Font("Lucida Grande", 12));

//comandos finais

controls.front;

CmdPeriod.doOnce{if(controls.isClosed.not, {controls.close})};
CmdPeriod.doOnce{if(w.isClosed.not, {w.close; buf1.free; buf2.free; meter.quit})};

});
)