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

  1. #define MAXTERMS 33
  2. #define MACH1 1080.0
  3. #define IWRAP(x,y) (((x)>=(y))?(x)-(y):(((x)<0)?(x)+(y):(x)))
  4. #define FABS(x) (((x)<0.0)?-(x):(x))
  5. #define SIZE 512
  6.  
  7. #include <stdio.h>
  8. #include <math.h>
  9. #include "ugens.h"
  10. #include "sfheader.h"
  11. #include "nobug.h"
  12.  
  13. extern SFHEADER sfdesc[NFILES];
  14. extern float array[SIZE],tabs[2];    /* for lineset */
  15. extern int lineset, space_called;
  16.  
  17. /* This is the main routine that is called by cmix. Its arguments are as
  18.    follows:
  19.  
  20.    place (inskip, outskip, dur, amp, rho [x], theta [y], recdist, rvbamp)
  21.  
  22.    The first 3 are as in mix.  "amp" is the amplitude factor for the input
  23.    sig. If "recdist" is positive, location of source is entered in polar
  24.    coordinates: rho (feet), theta (degrees from front, clockwise). If "rec-
  25.    dist" is neg., loc. entered in cartesian: x, y (in feet, listener at 0,0).
  26.    "recdist" is distance in feet between the "mikes" or "ears". "Rvbamp" is fac.
  27.    for reverberation, between 0 and 1.
  28.                                     */
  29. extern float rvb_time;         /* From space.c, for time limit. */
  30. extern int tapsize;            /* For allocating space for tap delay */
  31.  
  32. place (p,n_args)
  33. float *p;
  34. int n_args;
  35. {
  36.     char *calloc();
  37.     double Airdata[2][13][3]; 
  38.     double  Rho[2][13], Theta[2][13], Sig[2][13];
  39.     double Firtaps[2][13][MAXTERMS+1], Fircoeffs[2][13][MAXTERMS];   
  40.     double dist, R, T;
  41.     double wrap();
  42.     long outlocs[2][13], tap_set();
  43.     register long nsamps, tapcount, N, i, Nend;
  44.     int flag, ear_flag, intap, cartflag=0, z, j;
  45.     double rvbsig[2], roomsig[2];
  46.     float input[4], outbox[4], rvbamp, dur, amp;
  47.     double *tapdel;
  48.  
  49.     if(n_args != 8)
  50.     {
  51.         fprintf(stderr,"Wrong number of args for place!\n");
  52.         closesf();
  53.         return;
  54.     }
  55.     dur = p[2]; 
  56.     dur = ((dur > 0.0) ? dur - p[0] : -dur); 
  57.     setnote(p[0], dur, 0);           /* set input file */
  58.     nsamps = setnote(p[1], dur, 1);  /* set output file */
  59.     dist = p[6];
  60.     if (dist < 0) {
  61.         cartflag = 1;     /* cartesian coordinates */
  62.         dist = -dist;
  63.         fprintf(stderr, "Using cartesian coordinate system.\n");
  64.     }
  65.     if(sfchans(&sfdesc[0]) != 1) {
  66.         fprintf(stderr,"Input file must be 1-channel.\n");
  67.         return;
  68.     }
  69.     if(sfchans(&sfdesc[1]) != 2) {   
  70.         fprintf(stderr,"Output file must be 2-channel.\n");
  71.         return;
  72.     }
  73.     if(!space_called) {
  74.         fprintf(stderr,"You must call setup routine 'space' first!\n");
  75.         return;
  76.     }
  77.  
  78.     /* allocate space for tap delay based on room dimensions */
  79.  
  80.     if((tapdel = (double *) calloc((unsigned)(tapsize+8), sizeof(double))) == NULL)
  81.     {
  82.         fprintf(stderr, "Not enough memory for tap delay!\n");
  83.         return;
  84.     }
  85.  
  86.     /* flag for use of ear filters */
  87.  
  88.     ear_flag = 0;
  89.     if(dist < 1.0 && dist != 0.0) ear_flag = 1;
  90.  
  91.     z = SR/100;              /* the control rate for amp curve */
  92.     if(!lineset) {
  93.         for(i=0; i<SIZE; i++) array[i] = 1;
  94.         fprintf(stderr, "Setting phrase curve to all 1's.\n");
  95.         lineset = 1;
  96.     }
  97.     j = 0;
  98.     tableset(dur, SIZE, tabs);   /* set up table for amp */
  99.  
  100.     rvbamp = p[7];             /* amp factor for reverberated sig */
  101.     flag = 1;                  /* reset all filters, etc. */
  102.     rvb_reset(tapdel);        /* resets reverb & tap delay */
  103.     intap = 0;                 /* the starting element in tap delay */
  104.  
  105.     /* set up room */
  106.     R = p[4];
  107.     T = p[5];
  108.     if(roomtrig (R,T,dist,Rho,Theta,cartflag)) return; 
  109.  
  110.     /* set taps, return max samp */
  111.     tapcount = tap_set (Rho, outlocs, ear_flag);
  112.     airfil_set (Rho, flag, Airdata);
  113.     if (ear_flag)
  114.           earfil_set (Theta, flag, Fircoeffs, Firtaps);   
  115.  
  116.     /* the processing loop for the input signal */
  117.  
  118.     for (N = 0; N < nsamps; N++) 
  119.     {    
  120.         if(!GETIN(input,0)) break;      /* get input samp until EOF */ 
  121.         if(intap>=tapsize) intap -= tapsize;   /* input tap location */
  122.         while (!j--)
  123.         {
  124.             amp = tablei(N,array,tabs) * p[3];
  125.             j = z;
  126.         }
  127.         tapdel[intap] = input[0]*amp;          /* add to delay */
  128.         get_tap (intap, outlocs, Sig, tapdel); /* get delayed samps */
  129.         if (ear_flag)
  130.           ear (Sig, N, Fircoeffs, Firtaps); /* binaural angle filters */
  131.         air (Sig, Airdata);                  /* air absorpt. filters */
  132.         wall (Sig);                         /* wall absorpt. filters */
  133.         roomsig[0] = roomsig[1] = 0.0; 
  134.         for (i = 1; i < 13; ++i)            /* sum reflected signals */
  135.         {
  136.             roomsig[0] += Sig[0][i];
  137.             roomsig[1] += Sig[1][i]; 
  138.         }
  139.         /* scale by amp factor */
  140.         roomsig[0] *= rvbamp;  roomsig[1] *= rvbamp; 
  141.         RVB (roomsig, rvbsig, N);       /* run through reverberator */
  142.  
  143.         /* sum the dir. &  reverbed sigs  */
  144.         
  145.         outbox[0] = Sig[0][0]+roomsig[0]+rvbsig[0];
  146.         outbox[1] = Sig[1][0]+roomsig[1]+rvbsig[1];
  147.         ADDOUT(outbox,1);  
  148.         flag = 0;                     /* turn off reset flag */
  149.         intap++;
  150.     }
  151.  
  152.     /* the processing loop for the tap delay signal */
  153.     nsamps = (N < nsamps) ? N : nsamps;    /* if EOF reached above */
  154.     Nend = nsamps + tapcount;
  155.     for (N = nsamps; N < Nend; N++) 
  156.     {    
  157.         if(intap>=tapsize) intap -= tapsize;              
  158.         tapdel[intap] = 0.0;           
  159.         get_tap (intap, outlocs, Sig, tapdel); 
  160.         if (ear_flag)
  161.            ear (Sig, N, Fircoeffs, Firtaps); 
  162.         air (Sig, Airdata);   
  163.         wall (Sig);    
  164.         roomsig[0] = roomsig[1] = 0.0;
  165.         for (i = 1; i < 13; ++i)
  166.         {
  167.            roomsig[0] += Sig[0][i];
  168.            roomsig[1] += Sig[1][i];    
  169.         }
  170.         /* scale by amp factor */
  171.         roomsig[0] *= rvbamp;  roomsig[1] *= rvbamp; 
  172.         RVB (roomsig, rvbsig, N);    
  173.         outbox[0] = Sig[0][0] + roomsig[0] + rvbsig[0];
  174.         outbox[1] = Sig[1][0] + roomsig[1] + rvbsig[1];
  175.         ADDOUT(outbox,1);  
  176.         intap++;
  177.     }
  178.     /* clean out the reverb unit */
  179.     
  180.     i = 0;
  181.     N = Nend;  
  182.     Nend = N + (rvb_time + 0.25) * SR;
  183.     while (N < Nend) 
  184.     {
  185.         roomsig[0] = roomsig[1] = 0.0;
  186.         RVB(roomsig, rvbsig, N);
  187.         outbox[0] = rvbsig[0];
  188.         outbox[1] = rvbsig[1];
  189.         ADDOUT(outbox,1);
  190.         i++;
  191.         N++;
  192.     }
  193.     endnote(1);
  194.     cfree((char *)tapdel);
  195. }
  196.