Ejemplo n.º 1
0
int FILTSWEEP :: init(double p[], int n_args)
{
   nargs = n_args;
   float outskip = p[0];
   float inskip = p[1];
   float dur = p[2];
   float ringdur = p[4];
   nfilts = n_args > 5 ? (int) p[5] : 1;
   do_balance = n_args > 6 ? (bool) p[6] : true;
   inchan = n_args > 7 ? (int) p[7] : 0;            // default is chan 0

   if (rtsetinput(inskip, this) == -1)
      return DONT_SCHEDULE;
   if (inchan >= inputChannels())
      return die("FILTSWEEP", "You asked for channel %d of a %d-channel file.",
                                                      inchan, inputChannels());
   if (rtsetoutput(outskip, dur + ringdur, this) == -1)
      return DONT_SCHEDULE;
   insamps = (int) (dur * SR + 0.5);

   if (nfilts < 1 || nfilts > MAXFILTS)
      return die("FILTSWEEP",
               "Steepness (p5) must be an integer between 1 and %d.", MAXFILTS);
   for (int i = 0; i < nfilts; i++)
      filt[i] = new JGBiQuad(SR);

   if (do_balance) {
      balancer = new Balance(SR);
      balancer->setWindowSize(BALANCE_WINDOW_SIZE);
      scale = 1.0;
   }
   else
      scale = 1.0 / pow((double) nfilts, 1.8);     // just a guess; needs work

   amparray = floc(1);
   if (amparray) {
      int lenamp = fsize(1);
      tableset(SR, dur, lenamp, amptabs);
   }

   if (n_args < 11) {         // no p10 center freq PField, must use gen table
      cfarray = floc(2);
      if (cfarray == NULL)
         return die("FILTSWEEP", "Either use the center frequency pfield (p10) "
                    "or make an old-style gen function in slot 2.");
      int len = fsize(2);
      tableset(SR, dur, len, cftabs);
   }

   if (n_args < 12) {         // no p11 bandwidth PField, must use gen table
      bwarray = floc(3);
      if (bwarray == NULL)
         return die("FILTSWEEP", "Either use the bandwidth pfield (p11) "
                    "or make an old-style gen function in slot 3.");
      int len = fsize(3);
      tableset(SR, dur, len, bwtabs);
   }

   return nSamps();
}
void IINOISE::initamp(float dur, double p[], int ampindex, int ampgenslot)
{
	fastUpdate = Option::fastUpdate();
	if (fastUpdate) {
		// Prefer PField table, otherwise makegen
		int tablen = 0;
		amptable = (double *) getPFieldTable(ampindex, &tablen);
		if (amptable)
			ampmult = 1.0f;
		else {
			ampmult = p[ampindex];
			amptable = floc(ampgenslot);
			if (amptable)
				tablen = fsize(ampgenslot);
		}
		if (amptable)
			tableset(SR, dur, tablen, amptabs);
		else
			amp = ampmult;
	}
	else {
		// NB: ampmult never used, first amp set in doupdate
		amptable = floc(ampgenslot);
		if (amptable) {
			int tablen = fsize(ampgenslot);
			tableset(SR, dur, tablen, amptabs);
		}
	}
}
Ejemplo n.º 3
0
int AM::init(double p[], int n_args)
{
	float outskip = p[0];
	float inskip = p[1];
	float dur = p[2];
	inchan = (int) p[5];

	if (rtsetinput(inskip, this) == -1)
		return DONT_SCHEDULE;	// no input
	if (inchan >= inputChannels())
		return die("AM", "You asked for channel %d of a %d-channel file.",
														inchan, inputChannels());
	if (rtsetoutput(outskip, dur, this) == -1)
		return DONT_SCHEDULE;
	if (outputChannels() > 2)
		return die("AM", "Can't handle more than 2 output channels.");

	amptable = floc(1);
	if (amptable) {
		int amplen = fsize(1);
		tableset(SR, dur, amplen, amptabs);
	}

	int tablelen = 0;
	if (n_args > 7) {      // handle table coming in as optional p7 TablePField
		wavetable = (double *) getPFieldTable(7, &tablelen);
	}
	if (wavetable == NULL) { // use old gen slot
		wavetable = floc(2);
		if (wavetable)
			tablelen = fsize(2);
		else { // use default sine wave
			rtcmix_advise("AM", "No modulator wavetable specified, so using sine wave.");
			tablelen = 1024;
			wavetable = new double [tablelen];
			ownWavetable = true;
			const double twopi = M_PI * 2.0;
			for (int i = 0; i < tablelen; i++)
				wavetable[i] = sin(twopi * ((double) i / tablelen));
		}
	}

	modfreq = p[4];
	modosc = new Ooscili(SR, modfreq, wavetable, tablelen);

	if (modfreq == 0.0) {
		freqtable = floc(3);
		if (freqtable) {
			int len = fsize(3);
      	tableset(SR, dur, len, freqtabs);
		}
		else
			return die("AM", "If p4 is zero, old-style gen table 3 must "
									"contain modulator frequency curve.");
	}

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

	return nSamps();
}
Ejemplo n.º 4
0
int BEND1::init(double p[], int n_args)
{
// p0 = start; p1 = dur; p2 = pitch0 (oct.pc); p3 = pitch1 (oct.pc)
// p4 = gliss function #; p5 = fundamental decay time
// p6 = nyquist decay time; p7 = distortion gain; p8 = feedback gain
// p9 = feedback pitch (oct.pc); p10 = clean signal level
// p11 = distortion signal level; p12 = amp; p13 = update gliss nsamples
// p14 = stereo spread [optional]

	float dur = p[1];

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

	strumq1 = curstrumq[0];
	freq0 = cpspch(p[2]);
	diff = cpspch(p[3]) - freq0;
	tf0 = p[5];
	tfN = p[6];
	sset(SR, freq0, tf0, tfN, strumq1);

	dq = curdelayq;
	delayset(SR, cpspch(p[9]), dq);

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

	glissf = floc((int)p[4]);
	if (glissf) {
		int leng = fsize((int)p[4]);
		tableset(SR, p[1],leng,tags);
	}
	else
		return die("BEND1", "You haven't made the glissando function (table %d).",
						(int)p[4]);

	dgain = p[7];
	fbgain = p[8]/dgain;
	cleanlevel = p[10];
	distlevel = p[11];
	reset = (int)p[13];
	if (reset == 0) reset = 100;
	spread = p[14];

	d = 0.0;

	return nSamps();
}
Ejemplo n.º 5
0
int SFLUTE::init(double p[], int n_args)
{
// p0 = start; p1 = dur; p2 = noise amp; p3 = length1; p4 = length2
// p5 = amp multiplier; p6 = stereo spread (0-1) <optional>
// function slot 1 is the noise amp envelope
// function slot 2 is the out amp envelope

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

	dampcoef = .7;

	amparr = floc(1);
	if (amparr) {
		int len = fsize(1);
		tableset(SR, p[1], len, amptabs);
	}
	else
		return die("SFLUTE", "You haven't made the noise amp envelope (table 1).");

	oamparr = floc(2);
	if (oamparr) {
		int len = fsize(2);
		tableset(SR, p[1], len, oamptabs);
	}
	else
		return die("SFLUTE", "You haven't made the output amp envelope (table 2).");

	int imax = DELSIZE;
	mdelset(SR, del1,dl1,imax);
	mdelset(SR, del2,dl2,imax);
	dl1ptr = dl1;
	dl2ptr = dl2;
	del1ptr = del1;
	del2ptr = del2;

//	srrand(0.1);
	length1 = (int)p[3];
	length2 = (int)p[4];
	olength1 = length1;
	olength2 = length2;

	oldsig = 0; /* for the filter */

	amp = p[5];
	namp = p[2];
	spread = p[6];
	skip = (int)(SR/(float)resetval);

	aamp = oamp = 0.0;

	return nSamps();
}
Ejemplo n.º 6
0
int MOVE::localInit(double *p, int n_args)
{
    if (n_args < 6) {
        die(name(), "Wrong number of args.");
		  return(DONT_SCHEDULE);
	 }
    m_dist = p[4];
    m_rvbamp = p[5];
    m_inchan = n_args > 6 ? (int)p[6] : AVERAGE_CHANS;
    
    // copy global params into instrument
    
    if (get_path_params(&rholoc[0], &thetaloc[0], &cartflag, &mindiff) < 0) {
		  die(name(), "get_path_params failed.");
        return(DONT_SCHEDULE);
	}

	// treat mindiff as update rate in seconds
	if (mindiff > 0.0) {
		m_updateSamps = (int) (SR * mindiff + 0.5);
		if (m_updateSamps <= BUFLEN)
		{
	        setBufferSize(m_updateSamps);
#ifdef debug
			printf("buffer size reset to %d samples\n", getBufferSize());
#endif
		}
		// if update rate is larger than BUFLEN samples, set buffer size
		// to be some integer fraction of the desired update count, then
		// reset update count to be multiple of this.
		else {
		    int divisor = 2;
			int newBufferLen;
			while ((newBufferLen = m_updateSamps / divisor) > BUFLEN)
			    divisor++;
			setBufferSize(newBufferLen);
			m_updateSamps = newBufferLen * divisor;
#ifdef debug
			printf("buffer size reset to %d samples\n", getBufferSize());
#endif
		}
#ifdef debug
	    printf("updating every %d samps\n", m_updateSamps);
#endif
	}

    // tables for positional lookup
    
    tableset(SR, m_dur, ARRAYSIZE, tabr);
    tableset(SR, m_dur, ARRAYSIZE, tabt);
    
    return 0;
}
Ejemplo n.º 7
0
int CLAR::init(double p[], int n_args)
{
// p0 = start; p1 = dur; p2 = noise amp; p3 = length1; p4 = length2
// p5 = output amp; p6 = d2 gain; p7 = stereo spread (0-1) <optional>
// function slot 1 is the noise amp envelope
// function slot 2 is the output amp envelope

	int imax;

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

	dampcoef = .7;

	amparr = floc(1);
	if (amparr) {
		int lenamp = fsize(1);
		tableset(SR, p[1], lenamp, amptabs);
	}
	else
		rtcmix_advise("CLAR", "Setting noise amp curve to all 1's.");

	oamparr = floc(2);
	if (oamparr) {
		int olenamp = fsize(2);
		tableset(SR, p[1], olenamp, oamptabs);
	}
	else
		rtcmix_advise("CLAR", "Setting output amp curve to all 1's.");

	imax = DELSIZE;
	mdelset(SR, del1,dl1,imax);
	mdelset(SR, del2,dl2,imax);

//	srrand(0.1);
	length1 = (int)p[3];
	length2 = (int)p[4];

	oldsig = 0; /* for the filter */

	amp = p[5];
	namp = p[2];
	d2gain = p[6];
	spread = p[7];
	skip = (int)(SR/(float)resetval);

	aamp = oamp = 1.0;        /* in case amparr or oamparr are NULL */

	return nSamps();
}
Ejemplo n.º 8
0
int START::init(double p[], int n_args)
{
	float outskip = p[0];
	float dur = p[1];
	float pitch = p[2];
	float fdecay = p[3];
	float nydecay = p[4];
	float amp = p[5];
	int squish = (int)p[6];
	spread = p[7];
	deleteflag = (int)p[8];

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

	strumq1 = new strumq;
	curstrumq[0] = strumq1;
	float freq = cpspch(pitch);
	sset(SR, freq, fdecay, nydecay, strumq1);
	randfill(amp, squish, strumq1);

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

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

	return nSamps();
}
Ejemplo n.º 9
0
int FMINST::init(double p[], int n_args)
{
	nargs = n_args;
	float outskip = p[0];
	float dur = p[1];

	if (rtsetoutput(outskip, dur, this) == -1)
		return DONT_SCHEDULE;
	if (outputChannels() > 2)
		return die("FMINST", "Can't handle more than 2 output channels.");

	carfreqraw = p[3];
	if (carfreqraw < 15.0)
		carfreq = cpspch(carfreqraw);
	else
		carfreq = carfreqraw;

	modfreqraw = p[4];
	if (modfreqraw < 15.0)
		modfreq = cpspch(modfreqraw);
	else
		modfreq = modfreqraw;

	double *wavetable = NULL;
	int tablelen = 0;
	if (n_args > 8) {      // handle table coming in as optional p8 TablePField
		wavetable = (double *) getPFieldTable(8, &tablelen);
	}
	if (wavetable == NULL) {
		wavetable = floc(WAVET_GEN_SLOT);
		if (wavetable == NULL)
			return die("FMINST", "Either use the wavetable pfield (p8) or make "
                    "an old-style gen function in slot %d.", WAVET_GEN_SLOT);
		tablelen = fsize(WAVET_GEN_SLOT);
	}

	carosc = new Ooscili(SR, carfreq, wavetable, tablelen);
	modosc = new Ooscili(SR, modfreq, wavetable, tablelen);

	if (n_args < 10) {		// no p9 guide PField, must use gen table
		indexenv = floc(INDEX_GEN_SLOT);
		if (indexenv == NULL)
			return die("FMINST", "Either use the index guide pfield (p9) or make "
                    "an old-style gen function in slot %d.", INDEX_GEN_SLOT);
		int len = fsize(INDEX_GEN_SLOT);
		tableset(SR, dur, len, indtabs);
	}

	initamp(dur, p, 2, 1);
	if (fastUpdate) {
		minindex = p[5];
		indexdiff = p[6] - minindex;
		pan = p[7];
	}

	return nSamps();
}
int COMBFILT::init(double p[], int n_args)
{

  // p0 = outsk; p1 = insk; p2 = input dur; p3 = amp mult
  // p4 = pitch; p5 = a (input mult); p6 = b (delay mult); 
  // p7 = filter type (FIR/IIR)
  // p8 = wetdry;  p9 = inchan [optional]; p10 = spread [optional]
  // p11 = rise
  // p12 = sustain
  // p13 = decay
  // assumes function table 1 is the amplitude envelope

  if (rtsetinput(p[1], this) != 0)
	  return DONT_SCHEDULE;
  if (rtsetoutput(p[0], p[2], this) != 0)
	  return DONT_SCHEDULE;

  insamps = (int)(p[2] * SR);

  if (p[4] < 15.0)
	combfreq = cpspch(p[4]);
  else
	combfreq = p[4];
	
  // FIXME:  need check here:  combfreq < SR/2
  delay = (int)rint(SR/combfreq);

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

  amp = p[3];
  a = p[5];
  b = p[6];
  // FIXME:  need check here:  type < 2
  type = (int)p[7];
  skip = (int)(SR/(float)resetval); // how often to update amp curve
  inchan = (int)p[9];
  if ((inchan+1) > inputChannels())
	return die("COMBFILT", "You asked for channel %d of a %d-channel file.", 
				inchan,inputChannels());
  wetdry = p[8];
  spread = p[10];

  maxdelay = (int)rint(SR);
  runsamp = 0;

  return(this->mytag);
}
Ejemplo n.º 11
0
int PAN :: init(double p[], int n_args)
{
   nargs = n_args;
   float outskip = p[0];
   float inskip = p[1];
   float dur = p[2];
   inchan = n_args > 4 ? (int) p[4] : 0;                    // default is chan 0

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

   if (outputChannels() != 2)
      return die("PAN", "Output must be stereo.");

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

   amparray = floc(1);
   if (amparray) {
      int lenamp = fsize(1);
      tableset(SR, dur, lenamp, amptabs);
   }

   if (n_args < 7) {          // no p6 pan PField, must use gen table
      panarray = floc(2);
      if (panarray == NULL)
         return die("PAN", "Either use the pan pfield (p6) "
                    "or make an old-style gen function in slot 2.");
      int len = fsize(2);
      tableset(SR, dur, len, pantabs);
   }

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

   return nSamps();
}
Ejemplo n.º 12
0
int ROOM::init(double p[], int n_args)
{
   float outskip = p[0];
   float inskip = p[1];
   float dur = p[2];
   amp = p[3];
   inchan = n_args > 4 ? (int)p[4] : AVERAGE_CHANS;

   if (outputchans != 2)
      return die("ROOM", "Output must be stereo.");

   if (rtsetinput(inskip, this) == -1)
      return DONT_SCHEDULE;
   insamps = (int) (dur * SR + 0.5);

   if (inchan >= inputChannels())
      return die("ROOM", "You asked for channel %d of a %d-channel input file.",
                                                   inchan, inputChannels());
   if (inputChannels() == 1)
      inchan = 0;

   nmax = get_room(ipoint, lamp, ramp, SR);
   if (nmax == 0)
      return die("ROOM", "You need to call roomset before ROOM.");

   echo = new float[nmax];
   for (int i = 0; i < nmax; i++)
      echo[i] = 0.0;
   jpoint = 0;

#ifdef DEBUG
   printf("maximum delay = %d samples.\n", nmax);
#endif

   float ringdur = (float) nmax / SR;
   if (rtsetoutput(outskip, dur + ringdur, this) == -1)
      return DONT_SCHEDULE;

   amparray = floc(1);
   if (amparray) {
      int amplen = fsize(1);
      tableset(SR, dur + ringdur, amplen, amptabs);
   }
   else
      rtcmix_advise("ROOM", "Setting phrase curve to all 1's.");
   aamp = amp;                  /* in case amparray == NULL */

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

   return nSamps();
}
Ejemplo n.º 13
0
int JFIR :: init(double p[], int n_args)
{
   nargs = n_args;
   float outskip = p[0];
   float inskip = p[1];
   float dur = p[2];
   int order = (int) p[4];
   inchan = (int) p[5];

   if (rtsetinput(inskip, this) == -1)
      return DONT_SCHEDULE;
   insamps = (int) (dur * SR + 0.5);
   if (inchan >= inputChannels())
      return die("JFIR", "You asked for channel %d of a %d-channel file.",
                                                      inchan, inputChannels());
   float ringdur = (float) order / SR;
   if (rtsetoutput(outskip, dur + ringdur, this) == -1)
      return DONT_SCHEDULE;

   double *response_table = NULL;
	int tablelen = 0;
	if (n_args > 8) {      // handle table coming in as optional p8 TablePField
		response_table = (double *) getPFieldTable(8, &tablelen);
	}
	if (response_table == NULL) {
		response_table = floc(2);
		if (response_table == NULL)
			return die("JFIR", "Either use the frequency response pfield (p8) "
                    "or make an old-style gen function in slot 2.");
		tablelen = fsize(2);
	}

   if (order < 1)
      return die("JFIR", "Order must be greater than 0.");

   filt = new NZero(SR, order);
   filt->designFromFunctionTable(response_table, tablelen, 0, 0);
#ifdef PRINT_RESPONSE
   print_freq_response();
#endif

   amparray = floc(1);
   if (amparray) {
      int lenamp = fsize(1);
      tableset(SR, dur, lenamp, amptabs);
   }

   return nSamps();
}
Ejemplo n.º 14
0
int PANECHO::init(double p[], int n_args)
{
	float outskip = p[0];
	float inskip = p[1];
	float dur = p[2];
	float deltime0 = p[4];
	float deltime1 = p[5];
	float ringdur = p[7];
	inchan = n_args > 8 ? (int) p[8] : 0;

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

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

	if (rtsetoutput(outskip, dur + ringdur, this) == -1)
		return DONT_SCHEDULE;
	insamps = (int) (dur * SR + 0.5);

	if (outputChannels() != 2)
		return die("PANECHO", "Output must be stereo.");

	if (deltime0 <= 0.0 || deltime1 <= 0.0)
		return die("PANECHO", "Illegal delay times");

	long delsamps = (long) (deltime0 * SR + 0.5);
	delay0 = new Odelayi(delsamps);
	delsamps = (long) (deltime1 * SR + 0.5);
	delay1 = new Odelayi(delsamps);
	if (delay0->length() == 0 || delay1->length() == 0)
		return die("PANECHO", "Can't allocate delay line memory.");

	prevdeltime0 = prevdeltime1 = -999999999.9;		// force first update

	amptable = floc(1);
	if (amptable) {
		int amplen = fsize(1);
		tableset(SR, dur, amplen, amptabs);
	}

	return nSamps();
}
Ejemplo n.º 15
0
int NOISE :: init(double p[], int n_args)
{
   nargs = n_args;

   float outskip = p[0];
   float dur = p[1];

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

   amparray = floc(1);
   if (amparray) {
      int lenamp = fsize(1);
      tableset(SR, dur, lenamp, amptabs);
   }

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

   return nSamps();
}
Ejemplo n.º 16
0
int DEL1::init(double p[], int n_args)
{
	float outskip = p[0];
	float inskip = p[1];
	float dur = p[2];
	float deltime = p[4];
	inchan = n_args > 6 ? (int) p[6] : 0;
	float ringdur = n_args > 7 ? p[7] : deltime;

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

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

	if (rtsetoutput(outskip, dur + ringdur, this) == -1)
		return DONT_SCHEDULE;
	insamps = (int) (dur * SR + 0.5);

	if (outputChannels() != 2)
		return die("DEL1", "Output must be stereo.");

	if (deltime <= 0.0)
		return die("DEL1", "Illegal delay time (%g).", deltime);

	long delsamps = (long) (deltime * SR + 0.5);
	delay = new Odelayi(delsamps);
	if (delay->length() == 0)
		return die("DEL1", "Can't allocate delay line memory.");

	amptable = floc(1);
	if (amptable) {
		int amplen = fsize(1);
		tableset(SR, dur, amplen, amptabs);
	}

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

	return nSamps();
}
Ejemplo n.º 17
0
int REV :: init(double p[], int n_args)
{
   float outskip = p[0];
   float inskip = p[1];
   float dur = p[2];
   amp = p[3];
   int rvbtype = (int) p[4];
   float rvbtime = p[5];
   inchan = (int) p[7];

   if (rtsetoutput(outskip, dur + rvbtime, this) == -1)
      return DONT_SCHEDULE;
   if (rtsetinput(inskip, this) == -1)
      return DONT_SCHEDULE;
   insamps = (int) (dur * SR + 0.5);

   if (inchan >= inputChannels())
      return die("REV", "You asked for channel %d of a %d-channel file",
                                                    inchan, inputChannels());
   switch (rvbtype) {
      case 1:
         reverb = new PRCRev(SR, rvbtime);
         break;
      case 2:
         reverb = new JCRev(SR, rvbtime);
         break;
      case 3:
         reverb = new NRev(SR, rvbtime);
         break;
      default:
         return die("REV", "Unknown reverb type %d.", rvbtype);
   }

   amparray = floc(1);
   if (amparray) {
      int lenamp = fsize(1);
      tableset(SR, dur, lenamp, amptabs);
   }

   return nSamps();
}
Ejemplo n.º 18
0
int COMBIT::init(double p[], int n_args)
{
	float start = p[0];
	float inskip = p[1];
	float dur = p[2];
	frequency = p[4];
	rvbtime = p[5];
	inchan = n_args > 6 ? (int) p[6] : 0;
	pctleft = n_args > 7 ? p[7] : 0.0;
	float ringdur = n_args > 8 ? p[8] : rvbtime;

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

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

	if (rtsetoutput(start, dur + ringdur, this) == -1)
		return DONT_SCHEDULE;
	insamps = (int) (dur * SR + 0.5);

	if (frequency <= 0.0)
		return die("COMBIT", "Invalid frequency value!");
	float loopt = 1.0 / frequency;
	comb = new Ocombi(SR, loopt, loopt, rvbtime);
	if (comb->frequency() == 0.0)
		return die("COMBIT", "Failed to allocate comb memory!");

   frequency = -1.0;    // force update in run()

	amptable = floc(1);
	if (amptable) {
		int amplen = fsize(1);
		tableset(SR, dur + rvbtime, amplen, tabs);
	}

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

	return nSamps();
}
Ejemplo n.º 19
0
int DELAY::init(double p[], int n_args)
{
	float outskip = p[0];
	float inskip = p[1];
	float dur = p[2];
	float deltime = p[4];
	float ringdur = p[6];
	inchan = n_args > 7 ? (int) p[7] : 0;

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

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

	if (rtsetoutput(outskip, dur + ringdur, this) == -1)
		return DONT_SCHEDULE;
	insamps = (int) (dur * SR + 0.5);

	if (deltime <= 0.0)
		return die("DELAY", "Invalid delay time (%g)", deltime);

	long defaultDelay = MAX(100L, long(deltime * SR + 0.5));
	delay = new Odelayi(defaultDelay);
	// This is how we check for memory failure.
	if (delay->length() == 0)
		return die("DELAY", "Can't allocate delay line memory.");

	amptable = floc(1);
	if (amptable) {
		int amplen = fsize(1);
		tableset(SR, dur, amplen, amptabs);
	}

	return nSamps();
}
int TRANS3 :: init(double p[], int n_args)
{
   nargs = n_args;
   if (nargs < 5)
      return die("TRANS3",
                 "Usage: TRANS3(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;

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

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

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

   oneover_cpsoct10 = 1.0 / cpsoct(10.0);

	amptable = floc(1);
	if (amptable) {
		int amplen = fsize(1);
		tableset(SR, dur, amplen, amptabs);
	}

   return nSamps();
}
int REVMIX::init(double p[], int n_args)
{
   nargs = n_args;

   float outskip = p[0];
   float inskip = p[1];
   float dur = p[2];
   inchan = n_args > 4 ? (int) p[4] : 0;        // default is chan 0

   if (inskip == 0)
      return die("REVMIX", "Input start time must be greater than zero.");

   if (dur > inskip) {
      rtcmix_warn("REVMIX", "Duration must be greater than input start time. "
                     "Adjusting...");
      dur = inskip;
   }

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

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

   amparray = floc(1);
   if (amparray) {
      int amplen = fsize(1);
      tableset(SR, dur, amplen, amptabs);
   }

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

   return nSamps();
}
Ejemplo n.º 22
0
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();
}
Ejemplo n.º 23
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();
}
Ejemplo n.º 24
0
/* ----------------------------------------------------------------- init --- */
int MROOM::init(double p[], int n_args)
{
   float outskip = p[0];
   float inskip = p[1];
   float dur = p[2];
   ovamp = p[3];
   xdim = p[4];
   ydim = p[5];
   float rvbtime = p[6];
   reflect = p[7];
   innerwidth = p[8];
   inchan = n_args > 9 ? (int)p[9] : AVERAGE_CHANS;
   int quant = n_args > 10 ? (int)p[10] : DEFAULT_QUANTIZATION;

   if (outputchans != 2)
      return die("MROOM", "Requires stereo output.");

   float ringdur = (rvbtime > MAX_DELAY) ? rvbtime : MAX_DELAY;
   if (rtsetoutput(outskip, dur + ringdur, this) == -1)
      return DONT_SCHEDULE;

   if (rtsetinput(inskip, this) == -1)
      return DONT_SCHEDULE;
   insamps = (int)(dur * SR + 0.5);

   if (inchan >= inputChannels())
      return die("MROOM",
                 "You asked for channel %d of a %d-channel input file.",
                 inchan, inputChannels());
   if (inputChannels() == 1)
      inchan = 0;

// ***FIXME: input validation for trajectory points?
   int ntimes = get_timeset(timepts, xvals, yvals);
   if (ntimes == 0)
      return die("MROOM", "Must have at least two timeset calls before MROOM.");

   traject(ntimes);

   tableset(SR, dur, POS_ARRAY_SIZE, xpostabs);
   tableset(SR, dur, POS_ARRAY_SIZE, ypostabs);

   int delsamps = (int)(MAX_DELAY * SR + 0.5);
   delayline = new float[delsamps];
   delset(SR, delayline, deltabs, MAX_DELAY);

   /* Array dimensions taken from lib/rvbset.c (+ 2 extra for caution). */
   int rvbsamps = (int)((0.1583 * SR) + 18 + 2);
   rvbarrayl = new float[rvbsamps];
   rvbarrayr = new float[rvbsamps];
   rvbset(SR, rvbtime, 0, rvbarrayl);
   rvbset(SR, rvbtime, 0, rvbarrayr);

   amparray = floc(1);
   if (amparray) {
      int amplen = fsize(1);
      tableset(SR, dur, amplen, amptabs);
   }
   else
      rtcmix_advise("MROOM", "Setting phrase curve to all 1's.");
   aamp = ovamp;                  /* in case amparray == NULL */

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

   return nSamps();
}
Ejemplo n.º 25
0
int FREEVERB :: init(double p[], int n_args)
{
   float outskip = p[0];
   float inskip = p[1];
   float dur = p[2];
   roomsize = p[4];
   predelay_time = p[5];
   ringdur = p[6];
   damp = p[7];
   dry = p[8];
   wet = p[9];
   width = p[10];

   // Keep reverb comb feedback <= 1.0
   max_roomsize = (1.0 - offsetroom) / scaleroom;
   if (roomsize < 0.0)
      return die("FREEVERB", "Room size must be between 0 and %g.",
                                                               max_roomsize);
   if (roomsize > max_roomsize) {
      roomsize = max_roomsize;
      rtcmix_advise("FREEVERB", "Room size cannot be greater than %g. Adjusting...",
             max_roomsize);
   }
   int predelay_samps = (int) ((predelay_time * SR) + 0.5);
   if (predelay_samps > max_predelay_samps)
      return die("FREEVERB", "Pre-delay must be between 0 and %g seconds.",
                                             (float) max_predelay_samps / SR);
   if (damp < 0.0 || damp > 100.0)
      return die("FREEVERB", "Damp must be between 0 and 100%%.");
   if (dry < 0.0 || dry > 100.0)
      return die("FREEVERB", "Dry signal level must be between 0 and 100%%.");
   if (wet < 0.0 || wet > 100.0)
      return die("FREEVERB", "Wet signal level must be between 0 and 100%%.");
   if (width < 0.0 || width > 100.0)
      return die("FREEVERB", "Width must be between 0 and 100%%.");

   if (rtsetinput(inskip, this) == -1)
      return DONT_SCHEDULE;
   if (rtsetoutput(outskip, dur + ringdur, this) == -1)
      return DONT_SCHEDULE;
   insamps = (int) (dur * SR);

   if (inputChannels() > 2)
      return die("FREEVERB", "Can't have more than 2 input channels.");
   if (outputChannels() > 2)
      return die("FREEVERB", "Can't have more than 2 output channels.");

   rvb = new revmodel();

   rvb->setroomsize(roomsize);
   rvb->setpredelay(predelay_samps);
   rvb->setdamp(damp * 0.01);
   rvb->setdry(dry * 0.01);
   rvb->setwet(wet * 0.01);
   rvb->setwidth(width * 0.01);

   amparray = floc(1);
   if (amparray) {
      int lenamp = fsize(1);
      tableset(SR, dur, lenamp, amptabs);
   }

   return nSamps();
}
Ejemplo n.º 26
0
int BUTTER :: init(double p[], int n_args)
{
   nargs = n_args;
   float outskip = p[0];
   float inskip = p[1];
   float dur = p[2];
   amp = p[3];
   nfilts = n_args > 5 ? (int) p[5] : 1;
   do_balance = n_args > 6 ? (bool) p[6] : true;
   inchan = n_args > 7 ? (int) p[7] : 0;            // default is chan 0

   if (rtsetinput(inskip, this) != 0)
      return DONT_SCHEDULE;
   if (inchan >= inputChannels())
      return die("BUTTER", "You asked for channel %d of a %d-channel file.",
                                                      inchan, inputChannels());
   const float ringdur = 0.1;
   if (rtsetoutput(outskip, dur + ringdur, this) == -1)
      return DONT_SCHEDULE;
   insamps = (int) (dur * SR + 0.5);

   if (nfilts < 1 || nfilts > MAXFILTS)
      return die("BUTTER",
                 "Steepness (p5) must be an integer between 1 and %d.",
                 MAXFILTS);

   type = getFiltType(true);
   if (type == FiltInvalid)
      return die("BUTTER", "Type must be \"lowpass\", \"highpass\", "
                           "\"bandpass\", or \"bandreject\".");

   for (int i = 0; i < nfilts; i++)
      filt[i] = new Butter(SR);

   balancer = new Balance(SR);
   balancer->setWindowSize(BALANCE_WINDOW_SIZE);

   amparray = floc(1);
   if (amparray) {
      int lenamp = fsize(1);
      tableset(SR, dur, lenamp, amptabs);
   }

   if (n_args < 11) {      // no p10 filter freq PField, must use gen table
      cfarray = floc(2);
      if (cfarray == NULL)
         return die("BUTTER", "Either use the filter frequency pfield (p10) "
                    "or make an old-style gen function in slot 2.");
      int len = fsize(2);
      tableset(SR, dur, len, cftabs);
   }

   if (type == BandPass || type == BandReject) {
      if (n_args < 12) {   // no p11 filter bandwidth PField, must use gen table
         bwarray = floc(3);
         if (bwarray == NULL)
            return die("BUTTER", "Either use the filter bandwidth pfield (p11) "
                       "or make an old-style gen function in slot 3.");
         int len = fsize(3);
         tableset(SR, dur, len, bwtabs);
      }
   }

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

   return nSamps();
}
int REVERBIT::init(double p[], int n_args)
{
    float outskip = p[0];
    float inskip = p[1];
    float dur = p[2];
    reverbtime = p[4];
    reverbpct = p[5];
    rtchan_delaytime = p[6];
    cutoff = p[7];
    dcblock = n_args > 8 ? (p[8] != 0.0) : true;      // default is "yes"
    float ringdur = n_args > 9 ? p[9] : reverbtime + RVTSLOP;

    if (outputChannels() != 2)
        return die("REVERBIT", "Output must be stereo.");

    if (rtsetinput(inskip, this) == -1)
        return DONT_SCHEDULE;
    if (inputChannels() > 2)
        return die("REVERBIT", "Can't have more than 2 input channels.");

    if (rtsetoutput(outskip, dur + ringdur, this) == -1)
        return DONT_SCHEDULE;
    insamps = (int) (dur * SR);

    if (reverbtime <= 0.0)
        return die("REVERBIT", "Reverb time must be greater than 0.");

    if (reverbpct < 0.0 || reverbpct > 1.0)
        return die("REVERBIT",
                   "Reverb percent must be between 0 and 1 inclusive.");

    if (rtchan_delaytime <= 0.0)
        return die("REVERBIT", "Right chan delay time must be greater than 0.");

    if (cutoff < 0.0)
        return die("REVERBIT", "Cutoff frequency should be positive (or zero to "
                   "disable filter).");
    usefilt = (cutoff > 0.0);
    if (usefilt)
        toneset(SR, cutoff, 1, tonedata);
    else
        rtcmix_advise("REVERBIT", "Low-pass filter disabled.");

    float maxdeltime = rtchan_delaytime;
    // If delay time is very short, make delay line longer than necessary.
    if (rtchan_delaytime < MIN_DELAY)
        maxdeltime *= DELAY_FACTOR;
    int delsamps = (int) (maxdeltime * SR + 0.5);
    delarray = new float[delsamps];
    delset(SR, delarray, deltabs, maxdeltime);

    // Array dimensions taken from lib/rvbset.c (+ 2 extra for caution).
    int rvbsamps = (int)((0.1583 * SR) + 18 + 2);
    rvbarray = new float[rvbsamps];
    rvbset(SR, reverbtime, 0, rvbarray);

    amparray = floc(1);
    if (amparray) {
        int amplen = fsize(1);
        tableset(SR, dur, amplen, amptabs);
    }

    prev_in[0] = prev_out[0] = 0.0;         // for DC-blocker
    prev_in[1] = prev_out[1] = 0.0;

    return nSamps();
}
Ejemplo n.º 28
0
int SPECTACLE_BASE :: init(double p[], int n_args)
{
   float outskip = p[0];
   float inskip = p[1];
   inputdur = p[2];
   amp = p[3];
   ringdur = p[4];
   fft_len = (int) p[5];
   window_len = (int) p[6];
   window_type = getWindowType(p[7]);
   float overlap = p[8];

   /* Make sure FFT length is a power of 2 <= MAXFFTLEN and <= RTBUFSAMPS. */
   bool valid = false;
   for (int x = 1; x <= MAXFFTLEN; x *= 2) {
      if (fft_len == x) {
         valid = true;
         break;
      }
   }
   if (!valid || fft_len > MAXFFTLEN)
      return die(instname(), "FFT length must be a power of two <= %d",
                                                                  MAXFFTLEN);

// FIXME: now this isn't a problem; instead, decimation can't be larger
// than RTBUFSAMPS.  But must couch errmsg in terms of overlap and fft length,
// not decimation...
#if 0
   if (fft_len > RTBUFSAMPS)
      return die(instname(),
                 "FFT length must be a power of two less than or equal\n"
                 "to the output buffer size set in rtsetparams (currently %d).",
                 RTBUFSAMPS);
#endif
   half_fft_len = fft_len / 2;
   fund_anal_freq = SR / (float) fft_len;

   /* Make sure window length is a power of 2 >= FFT length. */
   valid = false;
   for (int x = fft_len; x <= MAXWINDOWLEN; x *= 2) {
      if (window_len == x) {
         valid = true;
         break;
      }
   }
   if (!valid)
      return die(instname(),
                     "Window length must be a power of two >= FFT length\n"
                     "(currently %d) and <= %d.", fft_len, MAXWINDOWLEN);

   /* Make sure overlap is a power of 2 in our safety range. */
   valid = false;
//FIXME: need to adjust MINOVERLAP so that iterations is never 0 in run()
// This might depend upon window_len??
   for (float x = MINOVERLAP; x <= MAXOVERLAP; x *= 2.0) {
      if (overlap == x) {
         valid = true;
         break;
      }
   }
   if (!valid)
      return die(instname(),
                 "Overlap must be a power of two between %g and %g.",
                 MINOVERLAP, MAXOVERLAP);
   int_overlap = (int) overlap;

   /* derive decimation from overlap */
   decimation = (int) (fft_len / overlap);

   DPRINT2("fft_len=%d, decimation=%d\n", fft_len, decimation);

   if (pre_init(p, n_args) != 0)    /* can modify ringdur */
      return DONT_SCHEDULE;

   iamparray = floc(1);
   if (iamparray) {
      int lenamp = fsize(1);
      tableset(SR, inputdur, lenamp, iamptabs);
   }
   else
      rtcmix_advise(instname(), "Setting input amplitude curve to all 1's.");

   oamparray = floc(2);
   if (oamparray) {
      int lenamp = fsize(2);
      tableset(SR, inputdur + ringdur, lenamp, oamptabs);
   }
   else
      rtcmix_advise(instname(), "Setting output amplitude curve to all 1's.");

   if (rtsetinput(inskip, this) == -1)
      return DONT_SCHEDULE;
   if (inchan >= inputChannels())
      return die(instname(), "You asked for channel %d of a %d-channel file.",
                                                   inchan, inputChannels());

   /* <latency> is the delay before the FFT looks at actual input rather than
      zero-padding.  Need to let inst run long enough to compensate for this.
   */
   window_len_minus_decimation = window_len - decimation;
   latency = window_len + window_len_minus_decimation;
   float latency_dur = latency * (1.0 / SR);
   if (rtsetoutput(outskip, latency_dur + inputdur + ringdur, this) == -1)
      return DONT_SCHEDULE;
   total_insamps = (int)(inputdur * SR);    /* without latency_dur */
   input_end_frame = total_insamps + latency;
   DPRINT1("input_end_frame=%d\n", input_end_frame);

   input = new float [window_len];           /* input buffer */
   output = new float [window_len];          /* output buffer */
   anal_window = new float [window_len];     /* analysis window */
   synth_window = new float [window_len];    /* synthesis window */
   fft_buf = new float [fft_len];            /* FFT buffer */
   anal_chans = new float [fft_len + 2];     /* analysis channels */

   if (make_windows() != 0)
      return DONT_SCHEDULE;

   /* Delay dry output by window_len - decimation to sync with wet sig. */
   drybuf = new float [decimation];
   dry_delay = new DLineN(window_len);
   dry_delay->setDelay((float) window_len_minus_decimation);

   /* Init iamp and oamp to starting amplitudes. */
   iamp = (iamparray == NULL) ? 1.0 : iamparray[0];
   oamp = (oamparray == NULL) ? amp : oamparray[0];

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

   if (post_init(p, n_args) != 0)
      return DONT_SCHEDULE;

   return nSamps();
}
Ejemplo n.º 29
0
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);
}
Ejemplo n.º 30
0
/* -------------------------------------------------------------- pre_init -- */
int TVSPECTACLE :: pre_init(double p[], int n_args)
{
   wetdry = n_args > 9 ? p[9] : 1.0;            /* default is 1 */
   inchan = n_args > 10 ? (int) p[10] : 0;      /* default is chan 0 */
   pctleft = n_args > 11 ? p[11] : 0.5;         /* default is center */

   if (wetdry < 0.0 || wetdry > 1.0)
      return die(instname(), "Wet/dry must be between 0 and 1.");

   eqtableA = floc(3);
   if (eqtableA) {
      int len = fsize(3);
      eqtableA = resample_functable(eqtableA, len, half_fft_len);
   }
   else
      return die(instname(), "You haven't made EQ function A (table 3).");

   eqtableB = floc(6);
   if (eqtableB) {
      int len = fsize(6);
      eqtableB = resample_functable(eqtableB, len, half_fft_len);
   }
   else
      return die(instname(), "You haven't made EQ function B (table 6).");

   deltimetableA = floc(4);
   if (deltimetableA) {
      int len = fsize(4);
      deltimetableA = resample_functable(deltimetableA, len, half_fft_len);
   }
   else
      return die(instname(),
                        "You haven't made delay time function A (table 4).");

   deltimetableB = floc(7);
   if (deltimetableB) {
      int len = fsize(7);
      deltimetableB = resample_functable(deltimetableB, len, half_fft_len);
   }
   else
      return die(instname(),
                        "You haven't made delay time function B (table 7).");

   /* Compute maximum delay lag and create delay lines for FFT magnitude
      and phase values.  Make ringdur at least as long as the longest
      delay time.  Remember that these delays function at the decimation
      rate, not at audio rate.
   */
   maxdelsamps = (long) (MAXDELTIME * SR / decimation + 0.5);
   float maxtime = 0.0;
   for (int i = 0; i < half_fft_len; i++) {

      /* Check delay time table A. */
      float deltime = deltimetableA[i];
      if (deltime < 0.0 || deltime > MAXDELTIME)
         return die(instname(),
                    "Delay times must be >= 0 and <= %g. (The value in "
                    "table A at %d is %g.)", MAXDELTIME, i, deltime);
      float samps = deltime * SR / (float) decimation;
      assert(samps <= maxdelsamps);
      if (deltime > maxtime)
         maxtime = deltime;

      /* Check delay time table B. */
      deltime = deltimetableB[i];
      if (deltime < 0.0 || deltime > MAXDELTIME)
         return die(instname(),
                    "Delay times must be >= 0 and <= %g. (The value in "
                    "table B at %d is %g.)", MAXDELTIME, i, deltime);
      samps = deltime * SR / (float) decimation;
      assert(samps <= maxdelsamps);
      if (deltime > maxtime)
         maxtime = deltime;

      mag_delay[i] = new DLineN(maxdelsamps);
      phase_delay[i] = new DLineN(maxdelsamps);
   }
   if (ringdur < maxtime)
      ringdur = maxtime;   /* but will still cut off any trailing feedback */

   DPRINT3("decimation=%d, maxdelsamps=%ld, ringdur=%g\n",
                                 decimation, maxdelsamps, ringdur);

   feedbacktableA = floc(5);
   if (feedbacktableA) {
      int len = fsize(5);
      feedbacktableA = resample_functable(feedbacktableA, len, half_fft_len);
   }
   else
      return die(instname(),
                     "You haven't made delay feedback function A (table 5).");

   feedbacktableB = floc(8);
   if (feedbacktableB) {
      int len = fsize(8);
      feedbacktableB = resample_functable(feedbacktableB, len, half_fft_len);
   }
   else
      return die(instname(),
                     "You haven't made delay feedback function B (table 8).");

   eqcurve = floc(9);
   if (eqcurve) {
      int len = fsize(9);
      if (check_curve(eqcurve, len, 0.0, 1.0))
         rtcmix_warn(instname(), "EQ curve values must be between 0 and 1.\n"
                          "Fixing...");
      tableset(SR, inputdur + ringdur, len, eqcurvetabs);
      eq_curve_weight = eqcurve[0];
   }
   else {
      rtcmix_advise(instname(), "Setting EQ table curve to all 0's (no table 9).");
      eq_curve_weight = 0.0;
   }

   deltimecurve = floc(10);
   if (deltimecurve) {
      int len = fsize(10);
      if (check_curve(deltimecurve, len, 0.0, 1.0))
         rtcmix_warn(instname(), "Delay time curve values must be between 0 and 1.\n"
                          "Fixing...");
      tableset(SR, inputdur + ringdur, len, deltimecurvetabs);
      deltime_curve_weight = deltimecurve[0];
   }
   else {
      rtcmix_advise(instname(), "Setting EQ table curve to all 0's (no table 10).");
      deltime_curve_weight = 0.0;
   }

   feedbackcurve = floc(11);
   if (feedbackcurve) {
      int len = fsize(11);
      if (check_curve(feedbackcurve, len, 0.0, 1.0))
         rtcmix_warn(instname(), "Feedback curve values must be between 0 and 1.\n"
                          "Fixing...");
      tableset(SR, inputdur + ringdur, len, feedbackcurvetabs);
      feedback_curve_weight = feedbackcurve[0];
   }
   else {
      rtcmix_advise(instname(), "Setting EQ table curve to all 0's (no table 11).");
      feedback_curve_weight = 0.0;
   }

//printf("deltimecurvetabs: %f, %f\n", deltimecurvetabs[0], deltimecurvetabs[1]);
   return 0;
}