Beispiel #1
0
int
PVTransBend::init(double *pp, int nargs)
{
	_totalCalls = (int) pp[0];
	if (_totalCalls <= 0) {
		return die("init_filter", "total_calls must be > 0");
	}
	_currentCall = 0;
	_exptable = new double[2048];
	if (nargs >= 3) {
		float *pvals = new float[nargs - 1];
		float timeZero = pp[1];
		float totalTime = pp[nargs - 2], prevTime = timeZero;
		int pIndex = 0;
		for (int arg=1; arg<nargs; arg+=2) {
			if (pp[arg] < prevTime) {
				return die("init_filter", "Time values must be in ascending order");
			}
			pvals[pIndex] = (pp[arg] - timeZero) * (kArraySize-1) / totalTime;	// position
			pvals[pIndex+1] = cpsoct(10.0 + octpch(pp[arg+1])) / cpsoct(10.0);	// transp
			pIndex += 2;
		}
		struct gen gen;
		gen.size = 2048;
		gen.nargs = nargs-2;
		gen.pvals = &pvals[1];	// skip initial time value
		gen.array = _exptable;
		gen.slot = -1;	// don't rescale
		gen5(&gen);
		delete [] pvals;
		return 0;
	}
	return die("init_filter", "PVTransBend usage: init_filter(total_calls, time0, intrvl0, ..., timeN, intrvlN)");
}
void TRANS3::doupdate()
{
   double p[7];
   update(p, 7);

   amp = p[3];
   if (amptable)
      amp *= tablei(currentFrame(), amptable, amptabs);
   pctleft = (nargs > 6) ? p[6] : 0.5;

   float newtransp = p[4];
   if (newtransp != transp) {
      transp = newtransp;
      _increment = cpsoct(10.0 + octpch(transp)) * oneover_cpsoct10;
#ifdef DEBUG
      printf("_increment: %g\n", _increment);
#endif
   }
}
Beispiel #3
0
int TRANS::init(double p[], int n_args)
{
   nargs = n_args;
   if (nargs < 5)
      return die("TRANS",
                 "Usage: TRANS(start, inskip, dur, amp, trans[, inchan, pan])");

   const float outskip = p[0];
   const float inskip = p[1];
   float dur = p[2];
   if (dur < 0.0)
      dur = -dur - inskip;
   inchan = (nargs > 5) ? (int) p[5] : 0;
   pctleft = (nargs > 6) ? p[6] : 0.5;

   if (rtsetoutput(outskip, dur, this) == -1)
      return DONT_SCHEDULE;
   if (rtsetinput(inskip, this) == -1)
      return DONT_SCHEDULE;

   if (inchan >= inputChannels()) {
      return die("TRANS", "You asked for channel %d of a %d-channel file.",
                                                  inchan, inputChannels());
   }

   // to trigger first read in run()
   inframe = RTBUFSAMPS;

   initamp(dur, p, 3, 1);

   oneover_cpsoct10 = 1.0 / cpsoct(10.0);
   if (fastUpdate)   // no transp updates
      _increment = cpsoct(10.0 + octpch(p[4])) * oneover_cpsoct10;

   return nSamps();
}
Beispiel #4
0
int TRANSBEND :: init(double p[], int n_args)
{
   float outskip, inskip, dur, transp, interval = 0, total_indur, dur_to_read;
   float averageInc;
   int pgen;

   if (n_args < 5) {
      die("TRANSBEND", "Wrong number of args.");
		return(DONT_SCHEDULE);
	}

   outskip = p[0];
   inskip = p[1];
   dur = p[2];
   amp = p[3];
   pgen = (int) p[4];
   inchan = (n_args > 5) ? (int) p[5] : 0;
   pctleft = (n_args > 6) ? p[6] : 0.5;

   if (dur < 0.0)
      dur = -dur - inskip;

   if (rtsetoutput(outskip, dur, this) == -1)
		return DONT_SCHEDULE;
   if (rtsetinput(inskip, this) == -1)
		return DONT_SCHEDULE;

   if (inchan >= inputChannels()) {
      return die("TRANSBEND", "You asked for channel %d of a %d-channel file.",
												   inchan, inputChannels());
	}
   pitchtable = floc(pgen);
   if (pitchtable) {
      int plen = fsize(pgen);
      float isum = 0;
      for (int loc = 0; loc < plen; loc++) {
          float pch = pitchtable[loc];
	      isum += octpch(pch);
      }
      interval = isum / plen;
#ifdef DEBUG
      printf("average interval: %g\n", interval);
#endif
      tableset(SR, dur, plen, ptabs);
   }
   else {
      die("TRANSBEND", "Unable to load pitch curve (table %d)!", pgen);
		return(DONT_SCHEDULE);
	}

   averageInc = (double) cpsoct(10.0 + interval) / cpsoct(10.0);

#ifdef NOTYET
   total_indur = (float) m_DUR(NULL, 0);
   dur_to_read = dur * averageInc;
   if (inskip + dur_to_read > total_indur) {
      warn("TRANSBEND", "This note will read off the end of the input file.\n"
                    "You might not get the envelope decay you "
                    "expect from setline.\nReduce output duration.");
      /* no exit() */
   }
#endif

   /* total number of frames to read during life of inst */
   in_frames_left = (int) (nSamps() * averageInc + 0.5);

   /* to trigger first read in run() */
   inframe = RTBUFSAMPS;

   amptable = floc(1);
   if (amptable) {
      int amplen = fsize(1);
      tableset(SR, dur, amplen, tabs);
   }
   else
      rtcmix_advise("TRANSBEND", "Setting phrase curve to all 1's.");

   skip = (int) (SR / (float) resetval);

   return nSamps();
}
INLINE double midipch(double pch)
{
	int midinote = (int) (((octpch(pch) - 3.0) * 12.0) + 0.5);
	return midinote;
}
INLINE double cpspch(double pch)
{
	double oct = octpch(pch);
	return cpsoct(oct);
}
static float getIncrement(float pchOct)
{
	return cpsoct(10.0 + octpch(pchOct)) * kOneover_cpsoct10;
}
int STGRANR::run()
{
        long i,attacksamps,j,thechunksamp,waitsamps,left,ngrains,rsamps;
        float *outp;
	float loc, ampfac, interval;
        double    frac;
	const int frameCount = framesToRun();
        
	if (in == NULL)        /* first time, so allocate it */
		in = new float [RTBUFSAMPS * inputChannels()];

//        if ( (durhi*(float)SR) > frameCount())
//		rtcmix_advise("STGRANR", "Grain duration larger than buffer.");
        
    outp = outbuf;               /* point to inst private out buffer */

	// figure out how many grains are in this chunk 
	ngrains = (int)((float)frameCount/(rate*(float)SR));	
        
	if ( ngrains  < 1 ) {
                if ( grainoverlap ) 
                    ngrains = 1;
                else {
					if ( (rrand()*.5+.5) < ((float)frameCount/(rate*(float)SR)) )
                        ngrains = 1;
                    else 
                         ngrains = 0;
                }
        }
        
        thechunksamp = 0;
        if ( ngrains ) {  
             for (i = 0; i < ngrains; i++) {
				attacksamps = frameCount/ngrains; // no grainoverlap yet
                transp = (float)prob(transplo, transpmid, transphi, transpti);
                interval = octpch(transp);
                increment = (double) cpsoct(10.0 + interval) / cpsoct(10.0);
                gdur = (float)prob(durlo,durmid,durhi,durti);
                grainsamps = (long)(gdur*(float)SR);    
                if ( grainsamps > attacksamps) {
                    overlapsample = grainsamps - attacksamps; // where to start in next attacksamps in envelop
                    grainoverlap = 1;
                    grainsamps = attacksamps;
                }
		ratevar = (float)prob(ratevarlo, ratevarmid, ratevarhi, ratevarti);
                waitsamps = (long)(ratevar*(float)(attacksamps - grainsamps));
		spread = (float)prob(loclo,locmid,lochi,locti);
		tableset(SR, gdur, grlen, tabg); 
		for ( j = 0; j < attacksamps; j++ ) {
			if (--branch < 0) { 
				aamp = tablei(currentFrame(), amptable, tabs) * amp;
				branch = skip;
			}
                        while (get_frame) {
                            if (inframe >= attacksamps) {
                                rtgetin(in, this, attacksamps * inputChannels());
                                inframe = 0;
                            }
                            oldersig[0] = oldsig[0];
                            oldsig[0] = newsig[0];
                            newsig[0] = in[(inframe * inputChannels())/* + inchan*/];
                            if ( inputChannels() == 2 ) {
                                oldersig[1] = oldsig[1];
                                oldsig[1] = newsig[1];
                                newsig[1] = in[(inframe * inputChannels())+1];
                            }
                            
                            inframe++;
                            incount++;
                    
                            if (counter - (double) incount < 0.5)
                                get_frame = 0;
                        }
                        if(( j < grainsamps + waitsamps) && ( j > waitsamps )) { 
                            ampfac = tablei(j-waitsamps,grenvtable,tabg);
                            frac = (counter - (double) incount) + 2.0;
                            outp[0] = interp(oldersig[0], oldsig[0], newsig[0], frac) * ampfac;
                            if (inputChannels() == 2 && outputChannels() == 2)  // split stereo files between the channels 
                                outp[1] = interp(oldersig[1], oldsig[1], newsig[1], frac) * ampfac;
                        }
                        else 
                            outp[0] = 0.0;
                        if (outputChannels() == 2 ) {  // split stereo files between the channels 
                            outp[1] = (1.0 - spread) * outp[0];
                            outp[0] *= spread;
                        }
						Instrument::increment(); // sample of whole note
                        thechunksamp++; // sample within chunk
                        outp += outputChannels();  
                        counter += increment;         /* keeps track of interp pointer */
                        if (counter - (double) incount >= -0.5)
                            get_frame = 1;
		}
                totalgrains++;
            }
        }
        else { // ngrains = 0
			for ( j = 0; j < frameCount; j++ ) {
                outp[0] = 0.0;
                if (outputChannels() == 2) outp[1] = 0.0;
                outp += outputChannels();
				Instrument::increment(); // sample of whole note
                thechunksamp++; // sample within chunk
           }
        }
 //       rtcmix_advise("STGRANR", "totalgrains: %ld\n",totalgrains);
        return thechunksamp;        
}
Beispiel #9
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;
}