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

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

#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 SIZE 512

#include <stdio.h>
#include <math.h>
#include "ugens.h"
#include "sfheader.h"
#include "nobug.h"

extern SFHEADER sfdesc[NFILES];
extern float array[SIZE],tabs[2];	/* for lineset */
extern int lineset, space_called;

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

   place (inskip, outskip, dur, amp, rho [x], theta [y], 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 */

place (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 dist, R, T;
	double wrap();
	long outlocs[2][13], tap_set();
	register long nsamps, tapcount, N, i, Nend;
	int flag, ear_flag, intap, cartflag=0, z, j;
	double rvbsig[2], roomsig[2];
	float input[4], outbox[4], rvbamp, dur, amp;
	double *tapdel;

	if(n_args != 8)
	{
		fprintf(stderr,"Wrong number of args for place!\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 */
	dist = p[6];
	if (dist < 0) {
		cartflag = 1; 	/* cartesian coordinates */
		dist = -dist;
		fprintf(stderr, "Using cartesian coordinate system.\n");
	}
	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;
	}
	if(!space_called) {
		fprintf(stderr,"You must call setup routine 'space' first!\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;
	}

	/* flag for use of ear filters */

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

	z = SR/100;		      /* the control rate for amp curve */
	if(!lineset) {
		for(i=0; i<SIZE; i++) array[i] = 1;
		fprintf(stderr, "Setting phrase curve to all 1's.\n");
		lineset = 1;
	}
	j = 0;
	tableset(dur, SIZE, tabs);   /* set up table for amp */

	rvbamp = p[7];             /* amp factor for reverberated sig */
	flag = 1;                  /* reset all filters, etc. */
	rvb_reset(tapdel);        /* resets reverb & tap delay */
	intap = 0;                 /* the starting element in tap delay */

	/* set up room */
	R = p[4];
	T = p[5];
	if(roomtrig (R,T,dist,Rho,Theta,cartflag)) return; 

	/* set taps, return max samp */
	tapcount = tap_set (Rho, outlocs, ear_flag);
	airfil_set (Rho, flag, Airdata);
	if (ear_flag)
	      earfil_set (Theta, flag, Fircoeffs, Firtaps);   

	/* the processing loop for the input signal */

	for (N = 0; N < nsamps; N++) 
	{	
		if(!GETIN(input,0)) break;      /* get input samp until EOF */ 
		if(intap>=tapsize) intap -= tapsize;   /* input tap location */
		while (!j--)
		{
			amp = tablei(N,array,tabs) * p[3];
			j = z;
		}
		tapdel[intap] = input[0]*amp;          /* add to delay */
		get_tap (intap, outlocs, Sig, tapdel); /* get delayed samps */
		if (ear_flag)
		  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]; 
		}
		/* scale by amp factor */
		roomsig[0] *= rvbamp;  roomsig[1] *= rvbamp; 
		RVB (roomsig, rvbsig, N);       /* run through reverberator */

		/* sum the dir. &  reverbed sigs  */
		
		outbox[0] = Sig[0][0]+roomsig[0]+rvbsig[0];
		outbox[1] = Sig[1][0]+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 (ear_flag)
		   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];    
		}
		/* scale by amp factor */
		roomsig[0] *= rvbamp;  roomsig[1] *= rvbamp; 
		RVB (roomsig, rvbsig, N);    
		outbox[0] = Sig[0][0] + roomsig[0] + rvbsig[0];
		outbox[1] = Sig[1][0] + 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];
		outbox[1] = rvbsig[1];
		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.