RANDOM:seed(17) --for getting the same piece always

-------- first the synthdefs ----------------
-- a piano synthdef
SynthDef("oteypiano", { out=0, freq=440, amp=0.5, t_gate=1,gate=1, release=0.1, rmin = 0.35,rmax =  2,rampl =  4,rampr = 8, rcore=1, lmin =  0.07,lmax =  1.4;lampl =  -4;lampr =  4, rho=1, e=1, zb=2, zh=0, mh=1.6, k=0.15, alpha=1, p=1, pos=0.142, loss = 1,detunes = 6,pan=0},function()
	vel = 1.5*amp --1.5
	--k = LinLin.kr(amp,0,1,0.2,0.5)
	local son = OteyPianoStrings.ar(freq, vel,t_gate, rmin,rmax,rampl,rampr, rcore, lmin,lmax,lampl,lampr, rho, e, zb, zh, mh, k, alpha, p, pos, loss,detunes*0.0001)
	son = son*EnvGen.ar{Env.asr(0,1,0.1),gate,doneAction=2}
	Out.ar(out, Pan2.ar(son *0.15,pan));
end):store();

-- soundboard for piano, will be set as an insert
SynthDef("pianosoundboard", { busin=0, busout=0,mix=0.9,fLPF=21000, size=2.5,gainS=1,gainH=1,bypass=0},function()
	local str=In.ar(busin,2); 
	
	local coefs = TA{199, 211, 223, 227, 229, 233, 239, 241 } *size
	local fdn = DWGSoundBoard.ar(str,nil,nil,mix,unpack(coefs:asSimpleTable()));
	
	local son = str*gainS + fdn*gainH
	son = LPF.ar(son,fLPF)
	son = Select.ar(bypass,{son,str})
	ReplaceOut.ar(busout,son)
end):store();


-- a reverb 
SynthDef("dwgreverb3band", { busin=0, busout=0,predelay=0.1,xover=200,rtlow=3,rtmid=2,fdamp=6000,len=1200},function()
	local source=Mix(In.ar(busin,2)); 
	source = DelayC.ar(source,0.5,predelay)
	source = DWGReverb3Band_16.ar(source,len,xover,rtlow,rtmid,fdamp)	
	ReplaceOut.ar(busout,source)
end):store();

-------------- this function will be used by AGS (Autogenerated stream) to make phrases
-- dura will be a table with one or two values
function frase(dura)
	print("frase",dura[1],dura[2])
	local pat ={}
	local duraTOT
	if dura[2] then -- if two values
		duraTOT = {LS{dura[1],dura[1]},dura[2]}
	else  -- if one value
		duraTOT = dura
	end
	pat.dur = RSinf(duraTOT) -- randomly chooses from duraTOT
	pat.amp = noisefStream{0.1,0.9}
	-- a random permutation 8 of notes played four times
	pat.note = LS(scramble{-12,0,7,choose{10,22},12,choose{16,14,17},19,24},4) + 48 
	pat.pan = noisefStream{-1,1}
	pat.pianopedal = true -- hold notes
	pat.t_gate = 1 -- retrigger piano string
	return PS(pat) --return the created PairsStream
end

----------- the player--------------------------------------------
-- OscPianoEP sends every freq to the same node (piano string)
-- pianopedal (true, false) avoids node releasing when true
piano = OscPianoEP{inst="oteypiano",sends={1}}

-- the generated phrases will have length halved each time ending in a chord
piano:Bind(LS{
	LS{AGS(frase,{1})}:rep(2),
	LS{AGS(frase,{0.5,1})}:rep(4),
	LS{AGS(frase,{0.5})}:rep(4),
	LS{AGS(frase,{0.25,0.5})}:rep(8),
	LS{AGS(frase,{0.25})}:rep(8),
	LS{AGS(frase,{0.125,0.25})}:rep(8),
	LS{AGS(frase,{0.125})}:rep(8),
	PS{dur=8,note = TA{-24,-12,0,2,7,12,16} + 60, strum = 1,amp = 0.9}
})

piano.inserts = {{"pianosoundboard"}}

------------------------- Master section -------------------
MASTER{level=db2amp(-5)}
Effects={FX("dwgreverb3band",db2amp(-10),nil,{rtmid=11*2,rtlow=11*2,len=2700})}

--FreqScope()
--DiskOutBuffer([[breathing.wav]])

theMetro:tempo(100)
theMetro:start()
