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.