.DS 
.ft C
double get_tempo(tempofun, abstart, absdur, limit)
	\fBFunction\fP *tempofun;
	double *abstart, absdur, limit;
{
	double dursum=0, x, ub, absend = *abstart + absdur;
	for (x = *abstart; x < absend; x = ub) {
		ub = ceil(x) == x ? x+limit : ceil(x);
		ub = ub > absend ? absend : ub;
		dursum += (ub \- x) * tempofun\->fyval[(int)x];
	}
	*abstart += absdur;
	return(dursum);
}

#define DUR 20
#define GRAIN 1.0

\fBFunction\fP *tempo;

\fBM_start\fP() {
	tempo = \fBGen\fP("step \-L20 0 .5 4 1 20 1");
}

\fBPlayer\fP \fIblat\fP(0, DUR)
{
	\fBInstance\fP double startsum; 
	double dur;

	dur = \fBExprs\fP(".5 .5 4 1 1 1 \fBKill\fP");
	\fBP4\fP = get_tempo(tempo, &startsum, dur, GRAIN);
	\fBP2\fP = \fBAbs_time\fP();
	\fBWait_until\fP(\fBP2\fP + \fBP4\fP);
}

\fBPlayer\fP \fIbleat\fP(0, DUR)
{
	\fBInstance\fP double startsum; 
	double dur;

	dur = \fBExprs\fP(".5 .5 4 1 1 1 \fBKill\fP");
	\fBP4\fP = get_tempo(tempo, &startsum, dur, GRAIN);
	\fBP2\fP = \fBAbs_time\fP();
	\fBWait_until\fP(\fBP2\fP + \fBP4\fP);
}
.ft R 
.DE
