示例#1
0
文件: randfuncs.c 项目: RTcmix/RTcmix
void tsrand()
{
	struct timeval tv;
	struct timezone tz;

	gettimeofday(&tv,&tz);
	srrand(tv.tv_usec);
}
示例#2
0
文件: VSTART1.cpp 项目: eriser/RTcmix
int VSTART1::init(double p[], int n_args)
{
// p0 = start; p1 = dur; p2 = pitch (oct.pc); p3 = fundamental decay time
// p4 = nyquist decay time; p5 = distortion gain; p6 = feedback gain
// p7 = feedback pitch (oct.pc); p8 = clean signal level
// p9 = distortion signal level; p10 = amp; p11 = squish
// p12 = low vibrato freq range; p13 = hi vibrato freq range
// p14 = vibrato freq depth (expressed in cps); p15 = random seed value
// p16 = pitch update (default 200/sec)
// p17 = stereo spread [optional]
// p18 = flag for deleting pluck arrays (used by FRET, BEND, etc.) [optional]
// assumes makegen 1 is the amplitude envelope, makegen 2 is the vibrato
// function, and makegen 3 is the vibrato amplitude envelope

    if (rtsetoutput(p[0], p[1], this) == -1)
        return DONT_SCHEDULE;

    strumq1 = new StrumQueue;
    strumq1->ref();
    curstrumq[0] = strumq1;
    freq = cpspch(p[2]);
    tf0 = p[3];
    tfN = p[4];
    sset(SR, freq, tf0, tfN, strumq1);
    randfill(1.0, (int)p[11], strumq1);

    dq = new DelayQueue;
    dq->ref();
    curdelayq = dq;
    delayset(SR, cpspch(p[7]), dq);
    delayclean(dq);

    amp = p[10];
    amptable = floc(1);
    if (amptable) {
        int amplen = fsize(1);
        tableset(SR, p[1], amplen, amptabs);
    }
    else {
        rtcmix_advise("VSTART1", "Setting phrase curve to all 1's.");
        aamp = amp;
    }

    vloc = floc(2);
    if (vloc == NULL)
        return die("VSTART1", "You need to store a vibrato function in gen num. 2.");
    vlen = fsize(2);

    vsibot = p[12] * (float)vlen/SR;
    vsidiff = vsibot - (p[13] * (float)vlen/SR);
    srrand((int)p[15]);
    vsi = ((rrand()+1.0)/2.0) * vsidiff;
    vsi += vsibot;
    vphase = 0.0;

    eloc = floc(3);
    if (eloc == NULL)
        return die("VSTART1", "You need to store a vibrato amp. envelope in gen num. 3.");
    int elen = fsize(3);
    tableset(SR, p[1], elen, tab);

    dgain = p[5];
    fbgain = p[6]/dgain;
    cleanlevel = p[8];
    distlevel = p[9];
    vdepth = p[14];
    reset = (int)p[16];
    if (reset == 0) reset = 200;
    spread = p[17];
    deleteflag = (int)p[18];

    d = 0.0;

    return nSamps();
}
示例#3
0
文件: sgran.c 项目: RTcmix/RTcmix
double
sgran(float p[], int n_args)
{
	long n,bgrainsamps,bgraindist,bgrainslide;
	long i,nsamps,gstt_var,count;
	long egrainsamps,egraindist,egrainslide;
	long grainsamps,grainslide,graindistdiff;
	float si=0.0,phase,val=0.0,amp,out[2],chb,freq;
	float tabs[2],tab[2],tab2[2],tab3[2],tab4[2],tab5[2];
	double *array,*wave,*envel,*rate_shape,*dur_shape,*loc_shape,*freq_shape;
	float gdist_inc;
	double gstt_per,lo,mid,hi,ti,slodiff,smiddiff,shidiff,stidiff;
	double dlodiff,dmiddiff,dhidiff,dtidiff;
	double llodiff,lmiddiff,lhidiff,ltidiff;
	double flodiff,fmiddiff,fhidiff,ftidiff;
	int len,j,z,chans,randflag=0;

#ifdef EMBEDDED
	int outrepos();
#endif
	float rrand();
	void srrand();
	double prob();

	if (p[37] > 0)
		srrand(p[37]);
   else
		srrand(3);

	nsamps = setnote(p[0],p[1],1); /* set file position */

	array = floc(1);             /* used to be setline  -JGG */
	if (array) {
		int amplen = fsize(1);
		tableset(SR(), p[1], amplen, tabs);
	}
	else
		rtcmix_advise("sgran", "Setting phrase curve to all 1's.");

	wave = floc(6); /* finds starting loc. of waveform */
	if (wave == NULL)
		die("sgran", "You haven't made the oscillator waveform (table 6).");
	len = fsize(6); /* length of playing waveform function */

	envel = floc(8);  /* NOTE: used to be floc(1), now stolen by setline  -JGG */
	if (envel == NULL)
		die("sgran", "You haven't made the grain envelope (table 8).");
	/* NOTE: fsize(8) called in loop below */

	bgrainsamps = grainsamps = p[14] * SR();
	bgraindist = p[3] * SR();
	bgrainslide = grainslide = bgraindist - bgrainsamps;

	egrainsamps = p[18] * SR();
	egraindist = p[4] * SR();
	egrainslide = egraindist - egrainsamps;

	graindistdiff = egraindist - bgraindist;

	rate_shape = floc(2);
	if (rate_shape == NULL)
		die("sgran", "You haven't made the grain density function (table 2).");
	tableset(SR(), p[1]-p[4],fsize(2),tab2);

	dur_shape = floc(3);
	if (dur_shape == NULL)
		die("sgran", "You haven't made the grain duration function (table 3).");
	tableset(SR(), p[1]-p[4],fsize(3),tab3);

	loc_shape = floc(4);
	if (loc_shape == NULL)
		die("sgran", "You haven't made the grain location function (table 4).");
	tableset(SR(), p[1]-p[4],fsize(4),tab4);

	freq_shape = floc(5);
	if (freq_shape == NULL)
		die("sgran", "You haven't made the grain frequency function (table 5).");
	tableset(SR(), p[1]-p[4],fsize(5),tab5);

	slodiff = (double)(p[9]-p[5])/nsamps; /* get stt zero/one differences */
	smiddiff = (double)(p[10]-p[6])/nsamps;
	shidiff = (double)(p[11]-p[7])/nsamps;
	stidiff = (double)(p[12]-p[8])/nsamps;

	dlodiff = (double)(p[17]-p[13]); /*get dur zero/one differences */
	dmiddiff = (double)(p[18]-p[14]);
	dhidiff = (double)(p[19]-p[15]);
	dtidiff = (double)(p[20]-p[16]);

	llodiff = (double)(p[25]-p[21]); /*get loc zero/one differences */
	lmiddiff = (double)(p[26]-p[22]);
	lhidiff = (double)(p[27]-p[23]);
	ltidiff = (double)(p[28]-p[24]);
	chb = p[21];

	if (p[29] < 0) 		/* if negative, noise is the input */
		randflag = 1;

	flodiff = (double)(p[33]-p[29]); /*freq zero/one differences */
	fmiddiff = (double)(p[34]-p[30]);
	fhidiff = (double)(p[35]-p[31]);
	ftidiff = (double)(p[36]-p[32]);

	z = 2;

	chans = sfchans(&sfdesc[1]); /* get file number of channels */
	amp = p[2];
	gstt_var = 0;
	count = 0;

	j = 0; /* "branch once a cycle" loop for amp envelope */

	for(i = 0; i < nsamps; i++) {
		count++;
		phase = 0;
		tableset(SR(), grainsamps/SR(),fsize(8),tab);
		if(!randflag) {
			lo = p[29] + flodiff*tablei(i,freq_shape,tab5);
			mid = p[30] + fmiddiff*tablei(i,freq_shape,tab5);
			hi = p[31] + fhidiff*tablei(i,freq_shape,tab5);
			ti = p[32] + ftidiff*tablei(i,freq_shape,tab5);
			lo = (lo > mid) ? mid : lo;
			hi = (hi < mid) ? mid : hi;
			ti = (ti < 0) ? 0 : ti; 
			freq = prob(lo, mid, hi, ti);
			si = freq * (float)len/SR(); 
		}

/*
	fprintf(stderr,"i: %ld, grainsamps: %ld, grainslide: %ld\n",i,grainsamps,grainslide);
*/

		for (n = 0; n < grainsamps; n++) {
			while (!j--) {   /* branch in here when j reaches 0 */
				float tmp = 1.0;
				if (array)
					tmp = tablei(i,array,tabs);
				val = amp * tablei(n,envel,tab) * tmp;
				j = ((grainsamps-n) > z) ? z : (grainsamps-n);
			}
			if(randflag)
				out[0] = rrand()*val;
			else
				out[0] =  oscili(val,si,wave,len,&phase);

			if (chans > 1) { /* stereo */
				out[1] = (1.0 - chb) * out[0];
				out[0] *= chb;
			}
			ADDOUT(out,1);
		}

		if((i+grainslide+gstt_var+grainsamps) < 0) {
			outrepos((grainslide),1);
			i += grainsamps;
			i += grainslide;
		}	
		else {
			outrepos((grainslide+gstt_var),1);
			i += grainsamps;
			i += grainslide;
			i += gstt_var;
		}

		lo = p[13] + dlodiff*tablei(i,dur_shape,tab3);
		mid = p[14] + dmiddiff*tablei(i,dur_shape,tab3);
		hi = p[15] + dhidiff*tablei(i,dur_shape,tab3);
		ti = p[16] + dtidiff*tablei(i,dur_shape,tab3);
		lo = (lo > mid) ? mid : lo;
		hi = (hi < mid) ? mid : hi;
		ti = (ti < 0) ? 0 : ti; 
		grainsamps = (long)(prob(lo, mid, hi, ti)*SR());


		/*	get percentage to vary next stt of grain */
		lo = p[5] + slodiff*i;
		mid = p[6] + smiddiff*i;
		hi = p[7] + shidiff*i;
		ti = p[8] + stidiff*i;
		lo = (lo > mid) ? mid : lo;
		hi = (hi < mid) ? mid : hi;
		ti = (ti < 0) ? 0 : ti; 
		gstt_per = prob(lo, mid, hi, ti);
		gstt_var = (long)(gstt_per*(grainsamps+grainslide)); 

/* calculate grainslide */
		gdist_inc = tablei(i,rate_shape,tab2);
		grainslide = (float)bgraindist + (float)graindistdiff*gdist_inc - grainsamps;

		lo = p[21] + llodiff*tablei(i,loc_shape,tab4);
		mid = p[22] + lmiddiff*tablei(i,loc_shape,tab4);
		hi = p[23] + lhidiff*tablei(i,loc_shape,tab4);
		ti = p[24] + ltidiff*tablei(i,loc_shape,tab4);
		lo = (lo > mid) ? mid : lo;
		hi = (hi < mid) ? mid : hi;
		ti = (ti < 0) ? 0 : ti; 
		chb = prob(lo, mid, hi, ti);
	}
	printf("\n%ld grains\n",count);
	endnote(1);

	return(0.0);
}
示例#4
0
int main(int argc, char **argv) {
   int ret, opt, conn, plugins_loaded = 0, banner_displayed = 0;
   unsigned long now, lastconn = time(NULL);
   FILE *urandom;

   runlevel = RL_OFFLINE;   

   while ((opt = getopt(argc, argv, "c:dj:u:vh")) != -1) {
      switch(opt) {
         case 'c':
            settings.config = optarg;
            break;
         case 'd':
            settings.daemonize = 1;
            break;
         case 'j':
            settings.chroot = optarg;
            break;
         case 'u':
            settings.chuser = optarg;
            break;
         case 'v':
            print_version();
            break;
         case 'h':
         default:
            print_usage(argv[0]);
            break;
      }
   }

   srand(time(NULL));
   
   urandom = fopen("/dev/urandom", "r");
   srrand(time(NULL) ^ getpid(), urandom);

   if (config_parse(settings.config)) {
      fprintf(stderr, "Unable to load configuration file '%s'.\n",
	settings.config);
      return -1;
   }

   if (checkconfig())
      return -1;

   if (settings.daemonize) {
      ret = fork();
      switch(ret) {
         case -1:
            fprintf(stderr, "Unable to fork to background\n");
            return -1;
        default:
            return 0;
      }
   }

   if (secure_it(settings.chroot, settings.chuser)) {
      fprintf(stderr, "Failed to chroot/setuid\n");
      return -1;
   }

#ifdef TLS
  if (gnutls_global_init() == GNUTLS_E_SUCCESS)
    atexit(gnutls_global_deinit);
  else
    fprintf(stderr, "Unable to initialize TLS library\n");
#endif

  if (dns_init() == -1)
      warn("Unable to initialize dns resolver\n");
  
   for(runlevel = RL_RUNNING; runlevel;) {
      if (irc_init() == -1) {
         warn("Unable to init irc data structure");
         return -1;
      }

      if(!plugins_loaded) {
         plugins_load();
         plugins_loaded = 1;
      }

      if(!banner_displayed) {
         banner_displayed = banner("Welcome to " PACKAGE_STRING
#ifdef SVN_REV
            "." SVN_REV
#endif
         );
      }

      while ((runlevel == RL_RUNNING) && (irc_conn() == -1)) {
         warn("Unable to establish irc connection\n");
         sleep(RECONNECT_DELAY);
      }

      lastconn = time(NULL);
      while(runlevel == RL_RUNNING)
         io_loop(100);
      
      irc_free();

      if((runlevel != RL_RUNNING) && plugins_loaded) { 
         plugins_unload();
         plugins_loaded = 0;
      }
      
      if(runlevel == RL_RELOAD) {
         printc("Reloading config file '%s'...\n", settings.config);
         if(config_parse(settings.config)) {
            warn("Error reloading config file.\n");
            runlevel = RL_OFFLINE;
         } else if(checkconfig()) {
            runlevel = RL_OFFLINE;
         }
         runlevel = RL_RUNNING;
      }

      conn = 0;
      now = time(NULL);
      if(runlevel != RL_OFFLINE) {
        runlevel = RL_RUNNING;
        if (now < lastconn + RECONNECT_DELAY)
          sleep(lastconn + RECONNECT_DELAY - now);
      }
   }

   if(urandom)
      fclose(urandom);
   return 0;
}
int STGRANR::init(double p[], int n_args)
{
/*  p0=start_time
*  p1=input start time
*  now p2 was p1=duration
*  p3=amplitude
*  p4=rate, p5-8 ratevar
*  p9-12 duration
*  p13-16 location
*  p17-20 transposition
*  p21 granlayers (not in use)
*  p22 seed
*  makegen slot 1 is amp env, makegen slot 2 is grain env
*/
	starttime = p[0];
	inskip = p[1];
	evdur = p[2];
	if (evdur < 0.0)
		evdur = -evdur - inskip;

	if (rtsetinput(inskip, this) == -1)
      return DONT_SCHEDULE; // no input
	if (rtsetoutput(starttime, evdur, this) == -1)
		return DONT_SCHEDULE;

	if (outputChannels() > 2)
		return die("STGRANR", "Can't handle more than 2 output channels.");

	amp = p[3];

	inframe = RTBUFSAMPS;
        
	amptable = floc(1);
	if (amptable) {
		alen = fsize(1);
		tableset(SR, evdur, alen, tabs);
	}
	else
		rtcmix_advise("STGRANR", "Setting phrase curve to all 1's.");
	grenvtable = floc(2);
	if (grenvtable) {
		grlen = fsize(2);
	}
	else
		rtcmix_advise("STGRANR", "Setting grain envelope to all 1's.");
        
	aamp = amp;
        
	skip = (int)(SR/(float)resetval);

	rate = p[4]; 
	ratevarlo  = (double)p[5];
	ratevarmid  = (double)p[6]; if (ratevarmid < ratevarlo ) ratevarmid = ratevarlo;
	ratevarhi  = (double)p[7]; if (ratevarhi < ratevarmid ) ratevarhi = ratevarmid;
	ratevarti  = (double)p[8];
	durlo  = (double)p[9];
	durmid  = (double)p[10]; if (durmid < durlo ) durmid = durlo;
	durhi  = (double)p[11]; if (durhi < durmid ) durhi = durmid;
   if ( durhi > rate ) {
 		die("STGRANR", "Grain durations %f sec. are larger than rate: %f seconds per grain.",durhi,rate);     
		return(DONT_SCHEDULE);
	}
	durti  = (double)p[12];
	loclo  = (double)p[13]; 
	locmid  = (double)p[14]; if (locmid < loclo ) locmid = loclo;
	lochi  = (double)p[15]; if (lochi < locmid ) lochi = locmid;
	locti  = (double)p[16];
	transplo  = (double)p[17];  
	transpmid  = (double)p[18]; 
        if (transpmid < transplo ) transpmid = transplo;
	transphi  = (double)p[19];  
        if (transphi < transpmid ) transphi = transpmid;
	transpti  = (double)p[20];
	granlyrs = (int)p[21];
	srrand((int)(p[22]));

	return nSamps();
}
示例#6
0
double
stgran(float p[], int n_args)
{
   int inchans, outchans, inchan;
   float indur, outdur, insk, outsk;
   long bgrainsamps, bgraindist, bgrainslide, inbgraindist;
   long i, nsamps, gstt_var, in_gstt_var, count, outcount, branch, skip;
   long s;                      /* sample number */
   long egrainsamps, egraindist, egrainslide, inegraindist;
   long grainsamps, grainslide, graindistdiff;
   long ingrainsamps, ingrainslide, ingraindistdiff;
   long  maxinsamps, maxoutsamps;
   float val, amp, aamp;
   float gdist_inc, in_gdist_inc;
   float tab1[2], tab2[2], tab3[2], tab4[2], tab5[2], tab6[2], tab7[2], tab8[2];
   double *in_rate_shape, *rate_shape, *dur_shape, *transp_shape, *amp_shape;
   double *loc_shape, *envel, *slarray;
   float *inarr, *outarr;
   double gstt_per, in_gstt_per, lo, mid, hi, ti, sig, table_val;
   double slodiff, smiddiff, shidiff, stidiff;
   double ilodiff, imiddiff, ihidiff, itidiff;
   double dlodiff, dmiddiff, dhidiff, dtidiff;
   double alodiff, amiddiff, ahidiff, atidiff, grainamp;
   double tlodiff, tmiddiff, thidiff, ttidiff;
   double llodiff, lmiddiff, lhidiff, ltidiff, pctleft = 0.0;
   double tlobeg, tmidbeg, thibeg, tloend, tmidend, thiend;
   double voldsig = 0.0, oldsig, newsig, interval, increment;
   double counter = 0., frac;
   register int incount = 1, getflag = 1;

   outsk = p[0];
   insk = p[1];
   outdur = p[2];
   indur = p[3];
   amp = p[4];

   setnote(insk, indur, INPUT);
   nsamps = setnote(outsk, outdur, OUTPUT);

   tlobeg = (double) octpch(p[33]);
   tmidbeg = (double) octpch(p[34]);
   thibeg = (double) octpch(p[35]);
   tloend = (double) octpch(p[37]);
   tmidend = (double) octpch(p[38]);
   thiend = (double) octpch(p[39]);

   inchan = (int) p[58];
   inchans = sfchans(&sfdesc[INPUT]);
   if (inchan >= inchans)
      die("stgran", "You asked for channel %d of a %d-channel file.",
                                                          inchan, inchans);
   outchans = sfchans(&sfdesc[OUTPUT]);
   if (outchans > 2)
      die("stgran", "Output file must be either mono or stereo.");

   /* allocate input and output buffers */
   interval = MAX(thibeg, thiend);      /* maximum transp. value (lin oct) */
   increment = cpsoct(10.0 + interval) / cpsoct(10.0);
   hi = MAX(p[31], p[27]) * SR();         /* maximum grain duration */
   maxinsamps = (long) (hi * increment + 1.0);
   inarr = malloc(maxinsamps * inchans * sizeof(float));
   if (inarr == NULL)
      die("stgran", "Can't allocate input buffer.");
   maxoutsamps = (long) (hi + 1.0);
   outarr = malloc(maxoutsamps * outchans * sizeof(float));
   if (outarr == NULL)
      die("stgran", "Can't allocate output buffer.");

   bgrainsamps = grainsamps = p[26] * SR();
   bgraindist = p[7] * SR();
   bgrainslide = grainslide = bgraindist - bgrainsamps;
   egrainsamps = p[30] * SR();
   egraindist = p[8] * SR();
   egrainslide = egraindist - egrainsamps;
   graindistdiff = egraindist - bgraindist;

   inbgraindist = p[5] * SR();
   inegraindist = p[6] * SR();
   ingraindistdiff = inegraindist - inbgraindist;

   in_rate_shape = floc(2);
	if (in_rate_shape == NULL)
		die("stgran",
				"You haven't made the grain input rate function (table 2).");
   tableset(SR(), indur - p[6], fsize(2), tab2);

   rate_shape = floc(3);
	if (rate_shape == NULL)
		die("stgran",
				"You haven't made the grain output rate function (table 3).");
   tableset(SR(), outdur - p[8], fsize(3), tab3);

   dur_shape = floc(4);
	if (dur_shape == NULL)
		die("stgran", "You haven't made the grain duration function (table 4).");
   tableset(SR(), outdur - p[8], fsize(4), tab4);

   transp_shape = floc(5);
	if (transp_shape == NULL)
		die("stgran",
				"You haven't made the grain transposition function (table 5).");
   tableset(SR(), outdur - p[8], fsize(5), tab5);

   amp_shape = floc(6);
	if (amp_shape == NULL)
		die("stgran", "You haven't made the grain amplitude function (table 6).");
   tableset(SR(), outdur - p[8], fsize(6), tab6);

   loc_shape = floc(7);
	if (loc_shape == NULL)
		die("stgran",
				"You haven't made the grain stereo location function (table 7).");
   tableset(SR(), outdur - p[8], fsize(7), tab7);

   envel = floc(8);           /* tableset in sample loop */
	if (envel == NULL)
		die("stgran", "You haven't made the grain envelope (table 8).");

   /* get infile stt var zero/one differences */
   ilodiff = (double) (p[13] - p[9]) / nsamps;
   imiddiff = (double) (p[14] - p[10]) / nsamps;
   ihidiff = (double) (p[15] - p[11]) / nsamps;
   itidiff = (double) (p[16] - p[12]) / nsamps;

   /* get outfile stt var zero/one differences */
   slodiff = (double) (p[21] - p[17]) / nsamps;
   smiddiff = (double) (p[22] - p[18]) / nsamps;
   shidiff = (double) (p[23] - p[19]) / nsamps;
   stidiff = (double) (p[24] - p[20]) / nsamps;

   /* get dur zero/one differences */
   dlodiff = (double) (p[29] - p[25]);
   dmiddiff = (double) (p[30] - p[26]);
   dhidiff = (double) (p[31] - p[27]);
   dtidiff = (double) (p[32] - p[28]);

   /* transp zero/one differences */
   tlodiff = tloend - tlobeg;
   tmiddiff = tmidend - tmidbeg;
   thidiff = thiend - thibeg;
   ttidiff = (double) (p[40] - p[36]);

   /* amp zero/one differences */
   alodiff = (double) (p[45] - p[41]);
   amiddiff = (double) (p[46] - p[42]);
   ahidiff = (double) (p[47] - p[43]);
   atidiff = (double) (p[48] - p[44]);

   /* loc zero/one differences */
   llodiff = (double) (p[53] - p[49]);
   lmiddiff = (double) (p[54] - p[50]);
   lhidiff = (double) (p[55] - p[51]);
   ltidiff = (double) (p[56] - p[52]);

   if (p[57] > 0)
      srrand(p[57]);
   else
      srrand(.3);    /* JGG: srrand takes unsigned int! */

   skip = SR() / (float) resetval;               /* control rate for amp curve */

   gstt_var = in_gstt_var = 0;
   count = 0;

   aamp = amp;                       /* in case there is no setline function */
   slarray = floc(1);
   if (slarray) {
      int len = fsize(1);
      tableset(SR(), outdur, len, tab1);
   }
   else
      rtcmix_advise("stgran", "Setting phrase curve to all 1's.");

   for (i = 0; i < nsamps; i++) {
      count++;
      table_val = (double) tablei(i, transp_shape, tab5);
      lo = tlobeg + (tlodiff * table_val);
      mid = tmidbeg + (tmiddiff * table_val);
      hi = thibeg + (thidiff * table_val);
      ti = p[36] + (ttidiff * table_val);
      lo = (lo > mid) ? mid : lo;
      hi = (hi < mid) ? mid : hi;
      interval = prob(lo, mid, hi, ti);                      /* in lin oct */
      increment = cpsoct(10.0 + interval) / cpsoct(10.0);    /* samp incr. */

      /* calculate next grain duration */
      table_val = (double) tablei(i, dur_shape, tab4);
      lo = p[25] + (dlodiff * table_val);
      mid = p[26] + (dmiddiff * table_val);
      hi = p[27] + (dhidiff * table_val);
      ti = p[28] + (dtidiff * table_val);
      lo = (lo > mid) ? mid : lo;
      hi = (hi < mid) ? mid : hi;
      grainsamps = (long) (prob(lo, mid, hi, ti) * SR());
      tableset(SR(), grainsamps / SR(), fsize(8), tab8);

      /* calculate grain amplitude */
      table_val = (double) tablei(i, amp_shape, tab6);
      lo = p[41] + (alodiff * table_val);
      mid = p[42] + (amiddiff * table_val);
      hi = p[43] + (ahidiff * table_val);
      ti = p[44] + (atidiff * table_val);
      lo = (lo > mid) ? mid : lo;
      hi = (hi < mid) ? mid : hi;
      grainamp = prob(lo, mid, hi, ti);

      /* calculate grain stereo location */
      if (outchans > 1) {
         table_val = (double) tablei(i, amp_shape, tab7);
         lo = p[49] + (llodiff * table_val);
         mid = p[50] + (lmiddiff * table_val);
         hi = p[51] + (lhidiff * table_val);
         ti = p[52] + (ltidiff * table_val);
         lo = (lo > mid) ? mid : lo;
         hi = (hi < mid) ? mid : hi;
         pctleft = prob(lo, mid, hi, ti);
      }

      /* get percentage to vary next stt of grain */
      lo = p[17] + slodiff * i;
      mid = p[18] + smiddiff * i;
      hi = p[19] + shidiff * i;
      ti = p[20] + stidiff * i;
      lo = (lo > mid) ? mid : lo;
      hi = (hi < mid) ? mid : hi;
      gstt_per = prob(lo, mid, hi, ti);
      gstt_var = (long) (gstt_per * (grainsamps + grainslide));

      /* calculate grainslide */
      gdist_inc = tablei(i, rate_shape, tab3);
      grainslide = (float) bgraindist
                     + (float) graindistdiff * gdist_inc - grainsamps;

      ingrainsamps = grainsamps * increment;

#ifdef DEBUG
      printf("ingrainsamps: %ld, maxinsamps: %ld\n", ingrainsamps, maxinsamps);
      assert(ingrainsamps <= maxinsamps);
      assert(grainsamps <= maxoutsamps);
#endif

      bgetin(inarr, INPUT, ingrainsamps * inchans);  /* read in grain */

      ingrainslide = ((float) inbgraindist) * increment
                      + (float) ingraindistdiff * increment - ingrainsamps;

      /* transpose the grain and write it to output file */
      oldsig = inarr[inchan];
      newsig = inarr[inchans + inchan];
      incount = 1;
      outcount = 0;
      counter = 0;
      branch = 0;
      for (s = 0; s < grainsamps; s++) {
         while (getflag) {
            voldsig = oldsig;
            oldsig = newsig;
            newsig = inarr[(incount * inchans) + inchan];
            incount++;
            if ((counter - (float) incount) < 0.5) {
               getflag = 0;
            }
         }
         /* update overall amp envelope at control rate */
         while (!branch--) {
            if (slarray)
               aamp = tablei(i, slarray, tab1) * amp;
            branch = skip;
         }
         /* update grain envelope on every sample */
         val = tablei(s, envel, tab8) * grainamp * aamp;

         frac = counter - incount + 2.0;               /* the interp value */

         sig = interp(voldsig, oldsig, newsig, frac) * val;

         if (outchans == 2) {
            outarr[outcount] = sqrt(pctleft) * sig;
            outarr[outcount + 1] = sqrt(1.0 - pctleft) * sig;
         }
         else
            outarr[outcount] = sig;

         counter += increment;            /* keeps track of interp pointer */
         if ((counter - (float) incount) >= -0.5) {
            getflag = 1;
         }
         outcount += outchans;
      }
      baddout(outarr, OUTPUT, grainsamps * outchans);
      inrepos(ingrainslide, INPUT);

      if ((i + grainslide + gstt_var + grainsamps) < 0) {
         outrepos(grainslide, OUTPUT);
         i += grainsamps;
         i += grainslide;
      }
      else {
         outrepos((grainslide + gstt_var), OUTPUT);
         i += grainsamps;
         i += grainslide;
         i += gstt_var;
      }
   }
   printf("\n%ld grains\n", count);
   endnote(OUTPUT);

   free(inarr);
   free(outarr);

   return 0.0;
}