home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Education Sampler 1992 [NeXTSTEP]
/
Education_1992_Sampler.iso
/
SoundAndMusic
/
cmix
/
rooms
/
place
/
place.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-02
|
6KB
|
196 lines
#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);
}