/* Module: adapt.c Purpose: Simulation of microphone response to moving point source in rectangular room. Using iterative approach: delays at time n are obtained from delays at time n-1 with one Newton-Raphson iteration. Date: 25 February 1992 Authors: B. Champagne Affiliation: INRS-Telecommunications Universite du Quebec Verdun, Quebec Canada H3E 1H6 Using the program: Main call: adapt audfilein coeff_file audfileout where audfilein: input file containing source signal audfileout: output file for storing microphone response coeff_file: file containing the coefficients of the symmetrical interpolation filter (the impulse response of this filter is assumed symmetrical, so that only the coefficients corresponding to the causal part of the response are stored) Changing room characteristics, microphone location and source trajectory: Room characteristics are defined with symbolic constants at the beginning of the program. They can be changed easily. The microphone location and the source trajectory are defined in a function called calc_gr_gdotr. The trajectory can be changed to accommodate different scenarios. External routines required: None. */ /* Standard libraries: */ #include #include #include /* Room dimensions in meters: */ #define Lx 10.0 #define Ly 10.0 #define Lz 3.0 /* Reflection coefficients: */ #define BETAXP 0.7 /* wall perpendicular to +x */ #define BETAXM 0.7 /* wall perpendicular to -x */ #define BETAYP 0.7 #define BETAYM 0.7 #define BETAZP 0.5 #define BETAZM 0.5 /* Speed of sound in air (m/s): */ #define C 343.0 /* Scaling factor for microphone output: */ #define AMP 200.0 /* Parameters related to interpolation process: */ #define FS 10000.0 /* sampling frequency of input data */ #define L 8 /* upsampling factor */ #define FSL FS*L /* interpolation rate */ #define NCOEF 59 /* interpolation filter has 2*NCOEF+1 taps */ #define SIZE (2800*L) /* size of circular buffer for interpolated samples */ /* Note: this buffer must be large enough to store all past samples that enter the microphone response at a given time. Knowledge of the reverberation time, or some other bound on the maximum allowed delay, is necessary to determine SIZE. */ #define K (NCOEF+L-1) /* NCOEF+L-1 */ /* Number of Newton-Raphson iterations: */ #define NITER 1 /* Macro substitution: */ #define MACFOR \ for (r1 = -n1; r1 < n1+1; r1++) \ for (r2 = -n2; r2 < n2+1; r2++) \ for (r3 = -n3; r3 < n3+1; r3++) { \ tmp1 = r1*Lx; \ tmp2 = r2*Ly; \ tmp3 = r3*Lz; \ tmp4 = tmp1*tmp1 + tmp2*tmp2 + tmp3*tmp3; \ if (tmp4 <= revrad2) { /* External variables: */ char audfilein[256], /* name of input audio file */ audfileout[256], /* name of output audio file */ coeff_file[256], /* name of file containing filter coefficients */ line[80]; /* line buffer for file access */ int next, /* index of next speech sample to be read */ r1,r2,r3, /* indices of images */ n1,n2,n3, /* limits of indices */ i0buf2; /* index pointing to most recent element of buf2 */ float speechin[40000], /* input speech samples */ speechout[40000], /* output speech samples */ tau[20][20][60], /* propagation delay for source images*/ taudot[20][20][60], /* delay rates */ intfilter[NCOEF+1], /* interpolation filter coefficients */ buf1[2*K+1], /* buffer containing zero-padded signal */ buf2[SIZE], /* circular buffer for interpolated samples */ revrad2, /* square of reverberation radius */ tmp1,tmp2,tmp3,tmp4; /* temporary variables */ double beta[20][20][60]; /* composite reflection coefficients */ void calc_room_params(), calc_beta(), calc_gr_gdotr(float time, float *grpt, float *gdotrpt), read_interpolate(), read_filter_coeffs(); FILE *filein, *fileout; /* Main function: */ main(int argc, char *argv[]) { int index, /* position of current sample */ nsamp, /* number of samples in audio file */ tauri, /* interpolated delay expressed in high rate samples */ nmax, /* number of samples to be processed */ i,j,k; /* dummy variables */ float scale, /* scaling factor for output speech samples */ time, /* time in seconds */ gr, /* distance function */ gdotr, /* derivative of distance function */ taur, /* delay for current mode */ taudotr, /* delay rate */ pi; /* 3.14... */ clock_t t1,t2,t3; /* used for timing */ switch (argc) { case 4: strcpy(audfilein,argv[1]); /* input audio file name */ strcpy(coeff_file,argv[2]); /* file of filter coefficients */ strcpy(audfileout,argv[3]); /* output audio file name */ break; case 3: case 2: printf("missing argument\n"); exit(-1); case 1: printf("This program calculates the response of a microphone\n"); printf("to a moving point source in a rectangular room\n"); exit(0); } /* end switch */ /* Open output file: */ fileout = fopen(audfileout, "w"); /* Preliminary calculations: */ t1 = clock()/CLOCKS_PER_SEC; pi = 4. * atan(1.0); scale = AMP / (4.*pi*C); /* Calculate reverberation time and related parameters: */ calc_room_params(); /* Calculate composite reflection coefficients: */ calc_beta(); /* Read coefficients of interpolation filter: */ read_filter_coeffs(); /* Open, read and close input speech file: */ filein = fopen(audfilein, "r"); nsamp = 0; while (fgets(line, 80, filein) != NULL) { sscanf(line, "%f", &speechin[nsamp]); nsamp++; } /* for (i=0; i<40; i++) printf("%16.7e \n", speechin[i]); */ /* Initialize zero-padded speech buffer (this buffer will be used to resample the input signal at the higher rate FSL: the zero-padded samples in this buffer will be convolved with the interpolation filter coefficients): */ next = 0; for (i=0; i=0; i--) { tmp = intfilter[0]*buf1[K-i]; for (j=1; j<=NCOEF; j++) tmp += intfilter[j]*(buf1[K-i-j] + buf1[K-i+j]); buf2[i0buf2+i] = tmp; } return; } /* END read_interpolate */