(
SynthDef("longplayer",{
arg buffer = 0,length = 1,realLength,
pitch1 = 1,pitch2 = 0.75,pitch3 = 1.5,pitch4 = 0.5,pitch5 = 0.66,pitch6 = 1.33,
startPos1 = 0,startPos2 = 0,startPos3 = 0,startPos4 = 0,startPos5 = 0,startPos6 = 0,
offset1 = 0.204589821,offset2 = 46.44188,offset3 = 329.185022,
offset4 = 2786.513362,offset5 = 11146.05345,offset6 = 19751.10132,
yteration;
var e,osc;
e = Env.new([0,1,1,0],[0.05,0.95,0.05]);
osc =
PlayBuf.ar(1,buffer,pitch1,startPos: (startPos1 + (offset1 * yteration))%realLength)
+
PlayBuf.ar(1,buffer,pitch2,startPos: (startPos2 + (offset2 * yteration))%realLength)
+
PlayBuf.ar(1,buffer,pitch3,startPos: (startPos3 + (offset3 * yteration))%realLength)
+
PlayBuf.ar(1,buffer,pitch4,startPos: (startPos4 + (offset4 * yteration))%realLength)
+
PlayBuf.ar(1,buffer,pitch5,startPos: (startPos5 + (offset5 * yteration))%realLength)
+
PlayBuf.ar(1,buffer,pitch6,startPos: (startPos6 + (offset6 * yteration))%realLength);
Out.ar([0,1],osc * EnvGen.kr(e,timeScale:length, doneAction: 2));
}).writeDefFile;
s.sendSynthDef("longplayer");
);
(
/*
SCREEN SIZE CONFIGURABLE
enter screen width in variable screenw
enter screen height in variable screenh
the soundfile has an extra section, the first two minutes, added to its end
this is to allow the 2 minute segment to slide seamlessly accross the join of
end and start points, as if the soundfile was glued together into a continuous circle
the upshot is that there are all kinds of work arounds in th GUI depending on sample rate and screen size, so that the range sliders show the correct positions.
this is written for 44100 sample rate
*/
var date;
var yr,mnth,dy,hr,min,sec,dumdum;
var leap,fullYearsRun,leapYears,notLeapYears,daysInFullYears,totalDays;
var daysInMonths,monthDays,leapMonthDays;
var onTime,listNo,extraIterations,timeCheck;
var onAt,extraIt,totalIterations,incList,realLength,lpCallList;
var timeZoneOffset;
//calculating time run
var minsrun,hrsrun,daysrun;
//GUI/////////////////////////
var daze,hrz,minz,scop,txt,rs1,rs2,rs3,rs4,rs5,rs6;
var screenw, screenh;
//for countdown
var onIn;
//for range sliders
var rangeList;
rangeList = #[rs1,rs2,rs3,rs4,rs5,rs6];
//screen dimensions
//width
screenw = 1680;
//height
screenh = 1050;
//London
timeZoneOffset = 12;
s.sendMsg("/b_allocRead",1,String.scDir ++"/sounds/20 20.aif");
lpCallList = List.fill(6,0);
//realLength is 20 mins 20 seconds * sample rate - here 44100
//actual soundfile is longer to emulate smooth transition across joined up start and end point
realLength = 53802000;
monthDays =#[0,31,59,90,120,151,181,212,243,273,304,334];
leapMonthDays =#[0,31,60,91,121,152,182,213,244,274,305,335];
incList = #[0.204589821,46.44188,329.185022, 2593.175981, 11146.05345, 19751.10132];
dumdum = List.fill(12,0);
date = Date.gmtime;
yr = date.year;
mnth = date.month;
dy = date.day;
hr = date.hour;
min = date.minute;
sec = date.second;
if(min.even,{onTime = (min + 2)%60;timeCheck = 240},{onTime = (min + 3)%60;timeCheck = 360});
if(min > 56,{onAt = onTime + 60},
{onAt = onTime});
["onAt "++onAt].postln;
if(yr%400 == 0,{leap = 1},
{if( yr%100 == 0,{leap = 0},
{if( yr%4 == 0,{leap = 1},{leap = 0})}
)
}
);
if(yr == 2000,{fullYearsRun = 0},
{fullYearsRun = yr - 2000}
);
if(yr ==2000,{leapYears = 0},
{leapYears = (fullYearsRun/400).asInt //one every 400 years
+ ((fullYearsRun/100).asInt * 24) //24 per century
+ (((fullYearsRun%100)-1)/4).asInt //one every 4 years
+ 1} //one for 2000
);
if(yr == 2000,{notLeapYears = 0},
{notLeapYears = fullYearsRun - leapYears});
daysInFullYears = (notLeapYears * 365) + (leapYears * 366);
//calculate how many days in full months so far this year
if(leap == 0,{daysInMonths = monthDays.at(mnth-1)},
{daysInMonths = leapMonthDays.at(mnth-1)});
// if ontime is stroke of midnight then add a day
// extraIt is extra iterations, number of hours and minutes passed in current day
if(min > 57,{hr = hr + 1;if(((hr + 1)%24) == 0,{dy = dy + 1;extraIt = 0},{extraIt = ((hr*30) + (onTime/2).floor)})},
{extraIt = ((hr*30) + (onTime/2).floor)});
totalDays = daysInFullYears + daysInMonths + (dy - 1);
listNo = totalDays*720;
// + 30 to work around missing hour bug in total iteration calc.
//not necessary ?
//totalIterations = listNo + extraIt + 30 ;
totalIterations = listNo + extraIt;
//time zone offset
totalIterations = totalIterations + (timeZoneOffset * 30);
["time zone offset is local time plus "++timeZoneOffset++" hours"].postln;
["date and time at 180 degrees longitude is "++(if(hr + timeZoneOffset > 23,{dy+1},{dy}))++" : "++mnth++" : "++yr++" "++((hr + timeZoneOffset)%24)++" hours : "++min++" minutes"].postln;
["total iterations is "++totalIterations].postln;
"this has been called from longplayer app".postln;
//startup
6.do({arg i;var temp;temp = (totalIterations*(incList@i))%realLength;lpCallList.put(i,temp)});
["start point list is "++lpCallList].postln;
minsrun = totalIterations * 2;
minz = minsrun%60;
if(minz == -0,{minz = 0});
hrsrun = ((minsrun/60).floor);
hrz = hrsrun%24;
if(hrz == -0,{hrz = 0});
daze = (hrsrun/24).floor;
//GUI////////////////////
/*
the soundfile has an extra section, the first two minutes, added to its end
this is to allow the 2 minute segment to slide seamlessly accross the join of
end and start points, as if the soundfile was glued together into a continuous circle
the upshot is that there are all kinds of work arounds in th GUI depending on smaple rate and screen size, so that the range sliders show the correct positions.
this is written for 44100 sample rate and 1240 pixel range slider
*/
w = SCWindow("Longplayer", Rect(0, 0, screenw, screenh));
l = SCCompositeView(w, Rect(0, 0, screenw+20, screenh/2.3));
c = Stethoscope.new(s, view:l);
w.front;
w.view.background = Color.new255(49,26,176);
txt = SCStaticText(w, Rect(20, screenh/2.3, screenh*0.8, 60));
txt.string = " Longplayer "++daze++" days "++hrz++" hours and "++minz++" minutes";
txt.font = Font("Courier", 15);
txt.backColor_(Color.new255(15,61,176));
x = SCStaticText(w, Rect(20, (screenh/2.3)+100, 200, 40));
x.string = " LAYERS ";
x.font = Font("Courier", 15);
x.backColor_(Color.new255(15,61,176));
rs1 = SCRangeSlider(w, Rect(20,(screenh/2.3)+170,screenw-40,40)).backColor_(Color.new255(171,29,227)).range_(0.0895);
rs2 = SCRangeSlider(w, Rect(20,(screenh/2.3)+220,screenw-40,40)).backColor_(Color.new255(171,29,227)).range_(0.0895);
rs3 = SCRangeSlider(w, Rect(20,(screenh/2.3)+270,screenw-40,40)).backColor_(Color.new255(171,29,227)).range_(0.0895);
rs4 = SCRangeSlider(w, Rect(20,(screenh/2.3)+320,screenw-40,40)).backColor_(Color.new255(171,29,227)).range_(0.0895);
rs5 = SCRangeSlider(w, Rect(20,(screenh/2.3)+370,screenw-40,40)).backColor_(Color.new255(171,29,227)).range_(0.0895);
rs6 = SCRangeSlider(w, Rect(20,(screenh/2.3)+420,screenw-40,40)).backColor_(Color.new255(171,29,227)).range_(0.0895);
//////////////////////
onIn = ((onAt * 60) - ((Date.localtime.minute * 60) + (Date.localtime.second))).post;
//start up post routine
t = Routine({
onIn.do
({arg j;
{txt.string = " Longplayer starting up in "++(onIn - j)++ " seconds"}.defer;
1.wait;
});
});
SystemClock.play(t);
//play routine
r = Routine({
onIn.wait;
inf.do({arg j;
x =
Synth("longplayer",['buffer',1,'length',120,'realLength',realLength,'startPos1',lpCallList@0,'startPos2',lpCallList@1,'startPos3',lpCallList@2,'startPos4',lpCallList@3,'startPos5',lpCallList@4,'startPos6',lpCallList@5,'yteration',j]);
totalIterations = totalIterations +1;
//set range sliders
//calculate start points
//59094000 is divisor to map samples to pixels in a 1240 pixel length range slider
{rs1.lo_((((lpCallList@0 + (incList@0 * j))%realLength)/59094000)%0.91044).range_(0.0895);
rs2.lo_((((lpCallList@1 + (incList@1 * j))%realLength)/59094000)%0.91044).range_(0.0895);
rs3.lo_((((lpCallList@2 + (incList@2 * j))%realLength)/59094000)%0.91044).range_(0.0895);
rs4.lo_((((lpCallList@3 + (incList@3 * j))%realLength)/59094000)%0.91044).range_(0.0895);
rs5.lo_((((lpCallList@4 + (incList@4 * j))%realLength)/59094000)%0.91044).range_(0.0895);
rs6.lo_((((lpCallList@5 + (incList@5 * j))%realLength)/59094000)%0.91044).range_(0.0895);
}.defer;
minsrun = totalIterations * 2;
//work around
minsrun = minsrun - 2;
minz = minsrun%60;
if(minz == -0,{minz = 0});
hrsrun = ((minsrun/60).floor);
hrz = hrsrun%24;
if(hrz == -0,{hrz = 0});
daze = (hrsrun/24).floor;
{txt.string = " Longplayer "++daze++" days "++hrz++" hours and "++minz++" minutes";
}.defer;
120.wait;
});
});
SystemClock.play(r);
)