ftp.nice.ch/pub/next/unix/audio/Cmix.N.s.tar.gz#/cmix/rooms/move/move.c

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

#define SIZE 512
#define MAXTERMS 33
#define MACH1 1080.0
#define IWRAP(x,y) (((x)>=(y))?(x)-(y):(((x)<0)?(x)+(y):(x)))
#define FABS(x) (((x)<0.0)?-(x):(x))
#define ATAN(x) ATANARRAY[(int)((x)*RADPT2)+512]
#include <stdio.h>
#include <math.h>
/* #include <malloc.h> */
#include "ugens.h"
#include "sfheader.h"
#include "nobug.h"

extern SFHEADER sfdesc[NFILES];

/* This is the main routine that is called by cmix. Its arguments are as
   follows:

   move (inskip, outskip, dur, amp, recdist, rvbamp)

   The first 3 are as in mix.  "amp" is the amplitude factor for the input
   sig. If "recdist" is positive, location of source is entered in polar
   coordinates: rho (feet), theta (degrees from front, clockwise). If "rec-
   dist" is neg., loc. entered in cartesian: x, y (in feet, listener at 0,0).
   "recdist" is distance in feet between the "mikes" or "ears". "Rvbamp" is fac.
   for reverberation, between 0 and 1.
									*/
extern float rvb_time;         /* From space.c, for time limit. */
extern int tapsize;            /* For allocating space for tap delay */
extern float rholoc[SIZE], thetaloc[SIZE];
extern int cartflag;		/* From path command--coordinate type */
extern int space_called;	/* Flag to be sure setup was done */
extern double mindiff;
extern double SINARRAY[1025], COSARRAY[1025], ATANARRAY[1025];
int earflag;

move (p,n_args)
float *p;
int n_args;
{
	char *calloc();
	double Airdata[2][13][3]; 
	double  Rho[2][13], Theta[2][13], Sig[2][13];
	double Firtaps[2][13][MAXTERMS+1], Fircoeffs[2][13][MAXTERMS];   
	double R_old, T_old, dist;
	double SIN(), COS(), wrap();
	double outlocs[2][13];
	long tap_set();
	register long nsamps, tapcount, N, i, Nend;
	int flag, intap; 
	double rvbsig[2], roomsig[2];
	float input[4], outbox[4], rvbamp, dur, tabr[2], tabt[2], amp;
	double *tapdel;

	if(n_args != 6)
	{
		fprintf(stderr,"Wrong number of args for move!\n");
		closesf();
		return;
	}
	dur = p[2]; 
	dur = ((dur > 0.0) ? dur - p[0] : -dur); 
	setnote(p[0], dur, 0);           /* set input file */
	nsamps = setnote(p[1], dur, 1);  /* set output file */
	amp = p[3];
	dist = p[4];
	if(sfchans(&sfdesc[0]) != 1)
	{
		fprintf(stderr,"Input file must be 1-channel.\n");
		return;
	}
	if(sfchans(&sfdesc[1]) != 2) 
	{   
		fprintf(stderr,"Output file must be 2-channel.\n");
		return;
	}

	/* allocate space for tap delay based on room dimensions */

	if((tapdel = (double *) calloc((unsigned)(tapsize+8), sizeof(double))) == NULL)
	{
		fprintf(stderr, "Not enough memory for tap delay!\n");
		return;
	}
	if(!space_called) {
		fprintf(stderr,"You must call setup routine 'space' first!\n");
		return;
	}
	/* flag for use of ear filters */

	earflag = 0;
	if(dist < 1.0 && dist != 0.0) earflag = 1;

	rvbamp = p[5];             /* amp factor for reverberated sig */
	flag = 1;                  /* reset all filters, etc. */
	tableset(dur, SIZE, tabr);
	tableset(dur, SIZE, tabt);
	rvb_reset(tapdel);        /* resets reverb & tap delay */
	intap = 0;                 /* the starting element in tap delay */
	R_old = -100000.0;
	T_old = 0.0;

	/* the processing loop for the input signal */

	for (N = 0; N < nsamps; N++) 
	{	
		double R, T, diff1, diff2;
		R = tablei(N, rholoc, tabr);
		T = tablei(N, thetaloc, tabt);
		diff1 = cartflag ? (R_old-R) : (R_old*SIN(T_old)-R*SIN(T));
		diff2 = cartflag ? (T_old-T) : (R_old*COS(T_old)-R*COS(T));
		if(FABS(diff1) > mindiff || FABS(diff2) > mindiff)   
		{ 
			R_old = R;
			T_old = T;
			if(roomtrig (R,T,dist,Rho,Theta)) return; 

		  /* set taps, return max samp */

			tapcount = tap_set (Rho, outlocs, earflag);
			airfil_set (Rho, flag, Airdata);
			if (earflag)
			      earfil_set (Theta, flag, Fircoeffs, Firtaps);   
		}
		if(!GETIN(input,0)) break;      /* get input samp until EOF */ 
		if(intap>=tapsize) intap -= tapsize;   /* input tap location */
		tapdel[intap] = input[0]*amp;          /* add to delay */
		get_tap (intap, outlocs, Sig, tapdel); /* get delayed samps */
		if (earflag)
		  ear (Sig, N, Fircoeffs, Firtaps); /* binaural angle filters */
		air (Sig, Airdata);                 /* air absorpt. filters */
		wall (Sig);                         /* wall absorpt. filters */
		roomsig[0] = roomsig[1] = 0.0; 
		for (i = 1; i < 13; ++i)            /* sum reflected signals */
		{
			roomsig[0] += Sig[0][i];
			roomsig[1] += Sig[1][i]; 
		}
		RVB (roomsig, rvbsig, N);       /* run through reverberator */

		/* sum the dir. &  reverbed sigs  */
		
		outbox[0] = Sig[0][0]+rvbamp*(roomsig[0]+rvbsig[0]);
		outbox[1] = Sig[1][0]+rvbamp*(roomsig[1]+rvbsig[1]);
		ADDOUT(outbox,1);  
		flag = 0;                     /* turn off reset flag */
		intap++;
	}
	/* the processing loop for the tap delay signal */
	nsamps = (N < nsamps) ? N : nsamps;	/* if EOF reached above */
	Nend = nsamps + tapcount;
	for (N = nsamps; N < Nend; N++) 
	{	
		if(intap>=tapsize) intap -= tapsize;              
		tapdel[intap] = 0.0;           
		get_tap (intap, outlocs, Sig, tapdel); 
		if (earflag)
		   ear (Sig, N, Fircoeffs, Firtaps); 
		air (Sig, Airdata);            
		wall (Sig);    
		roomsig[0] = roomsig[1] = 0.0;
		for (i = 1; i < 13; ++i)
		{
		   roomsig[0] += Sig[0][i];
		   roomsig[1] += Sig[1][i];    
		}
		RVB (roomsig, rvbsig, N);    
		outbox[0] = Sig[0][0] + rvbamp * (roomsig[0] + rvbsig[0]);
		outbox[1] = Sig[1][0] + rvbamp * (roomsig[1] + rvbsig[1]);
		ADDOUT(outbox,1);  
		intap++;
	}
	/* clean out the reverb unit */
	
	i = 0;
	N = Nend;  
	Nend = N + (rvb_time + 0.25) * SR;
	while (N < Nend) 
	{
		roomsig[0] = roomsig[1] = 0.0;
		RVB(roomsig, rvbsig, N);
		outbox[0] = rvbsig[0] * rvbamp;
		outbox[1] = rvbsig[1] * rvbamp;
		ADDOUT(outbox,1);
		i++;
		N++;
	}
	endnote(1);
	cfree((char *) tapdel);
}

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