ftp.nice.ch/pub/next/unix/audio/cmix.s.tar.gz#/cmix/sys/tempo.c

This is tempo.c in view mode; [Download] [Up]

#include <math.h>
#define TLEN 20  /* maximum number of time/tempo pairs */
#define TLENP 21
#define TWO  2.

float time[TLENP],temp[TLENP],rtime[TLENP],accel[TLENP],BASIS = 60.;
short tset = 0,npts;

tbase(p,n_args)
float *p;
{
	BASIS = p[0];
}

tempo(p,n_args)
float *p;
{
	short m;
	float dur,prvbt;
	if(!n_args) {
		printf("n_args = %d\n",n_args);
		printf("Tempo changes cleared out\n");
		tset = 0;
		return;
	}

	tset = 1;
	for(m=0;m<TLEN;m++) time[m]=temp[m]=rtime[m]=accel[m]=0;
	for(m=0,npts=1; m<TLEN; m += 2, npts++) {
		if((m) && (m >= n_args)) break;
		time[npts] = p[m];
		temp[npts] = p[m+1]/BASIS;
		}
	rtime[npts] = time[npts] = .999999e+10;
	temp[npts] = temp[npts-1];
	temp[0] = temp[1];
	time[0] = rtime[0] = accel[0] = prvbt = 0.;
	for(m=0; m<npts; m++) {
		dur = time[m+1] - time[m];
		if(!dur) {
			accel[m] = 0;
			rtime[m+1] = rtime[m];
			}
		else 	{
			accel[m] = (float)(pow((double)temp[m+1],TWO) - 
					pow((double)temp[m],TWO))/
					(2.*dur);
			if(!accel[m]) rtime[m+1] = dur/temp[m]+prvbt;
				else rtime[m+1] = (float)
					(sqrt(pow((double)temp[m],TWO)+
					(double)(TWO* accel[m]*dur))-temp[m])/
					accel[m] + prvbt;
		}
		prvbt = rtime[m+1];
	}
/*
for(m=0; m<=npts; m++) printf("%d %f %f %f %f\n",m,temp[m],accel[m],rtime[m],time[m]);
*/
}

float time_beat(timein)
float timein;
{
	int m = 0;
	float durp = 0;


	if(!tset) return(timein);

	if(timein) for(m=0; m<=npts; m++) {
		if(timein > time[m] && timein <= time[m+1]) {
			durp = timein-time[m];
			break;
		}
	}
	if(!accel[m]) return(durp/temp[m] + rtime[m]);
	return(((float)sqrt(pow((double)temp[m],TWO)+ 
		(double)(TWO * accel[m] * durp)) - temp[m])/
		accel[m] + rtime[m]);
}

float beat_time(beatin)    /* returns beats from times */
float beatin;
{
	int m=0;
	if(!tset) return(beatin);

	if(beatin) for(m=0; m<=npts; m++) 
		if(beatin > rtime[m] && beatin <= rtime[m+1]) break;
	if(!accel[m]) return((beatin-rtime[m])*temp[m] + time[m]);
	return(((float)pow((double)((beatin-rtime[m]) * accel[m]+temp[m]),TWO)
		-(float)pow((double)temp[m],TWO))/(TWO * accel[m]) + time[m]);
}

t(p,n_args)
float *p;
{
	float time_beat(),x,y;
	x = time_beat(p[0]);
	y = beat_time(p[0]);
	printf("%f %f %f\n",p[0],x,y);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.