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.