ftp.nice.ch/pub/next/unix/audio/cmix.s.tar.gz#/cmix/lpc/andylpcplay.c

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

#include "../H/ugens.h"
#include <stdio.h>
#define RESIDAMP     0
#define RMSAMP       1
#define THRESH       2
#define PITCH	     3
/* values in locs 0-3 of frame*/

#define MAXPOLES 32
int framsize;
int fprec;
int recsize;
int bprec;
int bpframe;
int npolem1;
int anal;
int i;
float cq,outold;
float FloatJunk;
float pow();
char dataset_name[80];
float thresh,randamp,randoff,unvoiced_rate;
int npoles,reson_is_on = 0;
int cf_fact,bw_fact;

lpcplay(p,n_args)
float *p;
{
	float amp,si,hn,phs,*f,srd2,magic,d,warpset();
	float c[MAXPOLES+4],past[MAXPOLES*2],frames,frameno,ampmlt,errno;
	int frame1;
	float ballpole(),alpvals[2048],buzvals[2048],pchval[2048];
	float *cpoint;
	float x,transposition,newpch;
	int jcount,seed,i,nsamps,counter;
	int nn,lastfr;
	float transp,lasttr,tranincr;
	float cps,tblvals[2],weight();
	float rsnetc[5];

	if(!n_args) {
		printf(" p[0]=starting time, p[1]=duration, p[2]=pitch,p[3]=frame1, p4=frame2 p[5]=amp, p[6]=warp\n");
		return;
	}
	sbrrand(.1);
	for(i=0; i<npoles*2; i++) past[i] = 0;

	if(anal <=0 ) {
		printf("%d !!!No open dataset!",anal);
		closesf();
	}
	srd2 = SR/2.;
	magic = 512./SR;
	jcount = phs = counter = 0; 
	seed = .1;
	cpoint = c + 4;
	printf("!!!\n");
	p[1] = (p[1] > 0.) ? p[1] : ((p[4] - p[3] + 1.)/112.);
	nsamps = setnote(p[0],p[1],0);
	frames = p[4] - p[3] + 1.;
	frame1 = (int)p[3];
	for(i=p[3]; i<= p[4]; i++) {
		d = i;
		getfr(d,c);
		pchval[i - (int)p[3]] = c[PITCH];
	}
	printf("pchval array is loaded!\n");
	if(ABS(p[2]) < 1.)  {
		FloatJunk=(p[2]/.12);
		FloatJunk=pow(2.0,FloatJunk);
		transposition=FloatJunk;
		transposition = (pow(2.0,(p[2]/.12)));
	}
	else	transposition = cpspch(p[2])/weight(cpspch(p[2]),p[3],p[4],thresh);
	printf("pchval array is loaded,transp=!\n,transposition");
	if(n_args == 6) {		
		printf("\Overall transposition: %f\n",transposition);
		for(i=frame1;i<=(int)p[4];i++) {
			pchval[(i - frame1)] *= transposition;
		}
	}
	else {
		nn=5;
		lastfr=frame1;
		lasttr=transposition;
		while((nn+=2)<n_args) {
			if(ABS(p[nn+1]) < 1.) {
				transp = pow(2.0,(p[nn+1]/.12));
			}
			else {
				transp = cpspch(ABS(p[nn+1]))/weight(cpspch(ABS(p[nn+1])),(float)lastfr,(p[nn]+1.),thresh);
			}
			tranincr=(transp-lasttr)/(p[nn]-lastfr);
			transp=lasttr;
			for(i=lastfr;i<(int)p[nn];i++) {
				pchval[i-frame1]*=transp;
				transp+=tranincr;
			}	
			lastfr=p[nn];
			lasttr=transp;
		}
		if(p[n_args-2] < p[4]) {
			/* last frame in couplets wasn't last frame in batch, so use
						base value from there to the end */
			transp = transposition;
			for(i=lastfr;i<(int)p[4];i++) {
				pchval[i-frame1]*=transp;
			}
		}
	}
	tableset(p[1],(int)(p[4]-p[3]+1),tblvals);
	amp = p[5];
	d = p[6];
	f = (float *)floc(1);
	for(i=0; i<5; i++) rsnetc[i]=0;

	warpinit();
	for(i=nsamps; i>0; i -=counter) {
		frameno = ((float)(nsamps - i)/nsamps)*frames + frame1;
		if(getfr(frameno,c) == -1) break;
		errno = (c[2] > thresh) ? 0 : 1;  
		ampmlt = (errno) ? amp * c[0] : amp * c[0] * randamp;
		cps = tablei(nsamps-i,pchval,tblvals);
		newpch = cps;
		if(reson_is_on) rsnset(cf_fact*cps, bw_fact*cf_fact*cps,
				(errno ? 1 : 2),0.,rsnetc);
		si = newpch * magic;
		hn = (int)(srd2/newpch);
		counter = (float)(SR/newpch);
		counter = (counter > i) ? i : counter;
		if(counter <= 0) break;

		if(errno) 
			bbuzz(ampmlt,si,hn,f,&phs,buzvals,counter);
		else
			brrand(ampmlt,buzvals,counter);
		if(d) {
			ampmlt *=  warpset(d,cpoint);
			bwarppol(buzvals,past,d,cpoint,alpvals,counter);
		}
		else
		{
			ballpole(buzvals,&jcount,npoles,
			past,cpoint,alpvals,counter);
		        if(reson_is_on) breson(alpvals,rsnetc,alpvals,counter);
		}
		baddout(alpvals,0,counter);   
	}
	endnote(0);
}
reson_on(p,n_args)
float *p;
{
	if(p[0]) reson_is_on = 1; 
	else {
		reson_is_on = 0;
		return;
	}
/* p0 is multiple of pitch to use, p1 is bw as multiple of center freq */
	cf_fact = p[0];
	bw_fact = p[1];
	printf(" reson turned on, cf_fact,bw_fact=%f %f\n",cf_fact,bw_fact);
	return;
}
float warppol(sig,past,d,c)
float sig,*past,d,*c;
{
	float temp1,temp2;
	int n;

	temp1 = past[npolem1];
	past[npolem1] = cq * outold - d * past[npolem1];
	for(n=npoles-2; n>=0; n--) {
		temp2 = past[n];
		past[n] = d * (past[n+1] - past[n]) + temp1;
		temp1 = temp2;
	}
	for(n=0;n<npoles;n++)  sig += c[n] * past[n];
	outold = sig;
	return(sig);
}
float warpset(d,c)     
float d,*c;
{
	int m;
	float cl;

	for(m=1; m<npoles; m++)   c[m] += d * c[m-1];
	cl = 1./(1.-d * c[npolem1]);
	cq = cl * (1. - d * d);
	return(cl);
}
warpinit()
{
	outold = 0;
}
bwarppol(sig,past,d,c,out,nvals)
float *sig,*past,d,*c,*out;
{
	float temp1,temp2;
	int i,n;
	for(i=0; i<nvals; i++) {
		temp1 = past[npolem1];
		past[npolem1] = cq * outold - d * past[npolem1];
		for(n=npoles-2; n>=0; n--) {
			temp2 = past[n];
			past[n] = d * (past[n+1] - past[n]) + temp1;
			temp1 = temp2;
		}
		for(n=0;n<npoles;n++)  *sig += c[n] * past[n];
		*out++ = outold = *sig++;
	}
}
getfr(frameno,c)
float frameno,*c;
{
	int frame,i,j;
	static float array[22*(MAXPOLES+4)];
	float fraction;
	static int oldframe = 0;
	static int endframe = 0;
	frame = (int)frameno;
	fraction = frameno - (float)frame;
	if(!((frame >= oldframe) && (frame < endframe))) {
		if(lseek(anal,((long)frame*(long)bpframe),0) == -1) {
			fprintf(stderr,"bad lseek on analysis file \n");
			return(-1);
		} 
		if(read(anal,(char *)array,bprec) <= 0) {
			fprintf(stderr,"reached eof on analysis file \n");
			return(-1);
		}
		oldframe = frame;
		endframe = oldframe + fprec - 1;
	}

	for(i=(frame-oldframe)*framsize,j=0; j<framsize; i++,j++)  
		*(c+j) = *(array+i) + fraction * (*(array+i+framsize) 
		    - *(array+i));
	return(0);
}
static	long	randx = 1;

/*
srrand(x)
unsigned x;
{
	randx = x;
}
*/
float table(nsample,array,tab)

long nsample;
float *array,*tab;

{
	register loc = ((float)(nsample)/(*tab)) * *(tab+1);
	if(loc >= *(tab+1)) loc = *(tab+1);
	return(*(array + loc));
}
float weight(newpch,frame1,frame2,throsh)
float newpch,frame1,frame2,throsh;
{
	float c[MAXPOLES+4];
	int i;
	float xweight,sum;
	xweight = sum = 0;
	for(i=(int)frame1; i<(int)frame2; i++) {
		getfr((float)i,c);
		if(c[THRESH] <= throsh) {
			xweight += c[RMSAMP];
			sum += (c[PITCH] * c[RMSAMP]);
		}
	}
	return(sum/xweight);
}

dataset(p,n_args)
/* p1=dataset name, p2=npoles */
float *p;
int n_args;
{
	char *name;
	int i;

	fprec=22;
	if(n_args>1) {
		npoles=p[1];
		npolem1=npoles-1;
		framsize=npoles+4;
		recsize=fprec*framsize;
		bprec=recsize*FLOAT;
		bpframe=framsize*FLOAT;
	}
	lpcinit();
	i=(int)p[0];
	name=(char *)i;
	if(strcmp(name,dataset_name)== 0) {
		printf("\n%s is already open.\n",name);
		return;
	}
	strcpy(dataset_name,name);
	if((anal = open(name,0)) <= 0) {
		printf("Can't open %s\n",name);
		closesf();
	}
	printf("\nOpened dataset %s.\n",name);
	printf("anal is %d",anal);
}

lpcstuff(p,n_args)
/* p1=thresh, p2=random amp, p3=unvoiced rate */
float *p;
int n_args;
{
	if(n_args>0)
		thresh=p[0];
	if(n_args>1)
		randamp=p[1];
	if(n_args>2)
		unvoiced_rate=p[2];
	printf("\nAdjusting settings for %s.\n",dataset_name);
	printf(" --------------------------------------- \n");
	printf("Thresh: %f     Randamp: %f\n",thresh,randamp);
	if(unvoiced_rate == 1)
		printf("Unvoiced frames played at normal rate.\n\n");
	else
		printf("Unvoiced frames played at same rate as voiced 'uns.\n\n");
}

lpcinit()
{
	recsize=framsize*fprec;
	bprec=recsize*FLOAT;
	bpframe=framsize*FLOAT;
}

/* block version of rrand */
/* a modification of unix rand() to return floating point values between
   + and - 1. */


sbrrand(x)
unsigned x;
{
	randx = x;
}
brrand(am,a,j)
float am,*a;
{
	int k;
	for(k=0; k<j; k++) {
		int i = ((randx = randx*1103515245 + 12345)>>16) & 077777;
		*a++ = (float)(i/16384. - 1.) * am;
	}
}

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