Example #1
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();
}
Example #2
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();
}
Example #3
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();
}
Example #4
0
/* setup filters for IIR instruments

   p0 - center frequency
        if < 15, indicates oct.pc format instead of Hz
        if negative, abs. value is multiplier of first frequency given
   p1 - bandwidth (Hz)
        if negative, abs. value is percent (from 0 to 1) of frequency
   p2 - amplitude multiplier

   followed by additional triplets for a total of 64 filters.
*/
double IIR_setup(float p[], int n_args)
{
	int i, j;
	float first = 1.0f;

	rtcmix_advise("IIR setup", "centerfreq    bandwidth  relative amp");

	for (i = 0, j = 0; i < n_args; i += 3, j++)  {
		float cf, bw, amp;

		if (j == MAXFILTER)
			return die("IIR setup", "Can't have more than %d filters.", MAXFILTER);

		if (p[i] < 0.0)
			cf = -p[i] * first;
		else
			cf = (p[i] < 15.0) ? cpspch(p[i]) : p[i];
		if (i == 0)
			first = cf;
		bw = p[i + 1] < 0.0 ? -p[i + 1] * cf : p[i + 1];
		amp = p[i + 2];

		_filter_spec[j].cf = cf;
		_filter_spec[j].bw = bw;
		_filter_spec[j].amp = amp;

		rtcmix_advise(NULL, "            %10.4f %10.4f %10.4f", cf, bw, amp);
	}
	_num_filters = j;
	return (double) _num_filters;
}
Example #5
0
int STRUM2::init(double p[], int n_args)
{
	_nargs = n_args;
	const float outskip = p[0];
	const float dur = p[1];

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

	if (outputChannels() > 2)
		return die("STRUM2", "Use mono or stereo output only.");

	_rawfreq = p[3];
	float freq = (_rawfreq < 15.0) ? cpspch(_rawfreq) : _rawfreq;

	int squish = int(p[4]);

	float fundDecayTime = p[5];
	if (fundDecayTime < kMinDecay)
		fundDecayTime = kMinDecay;
	float nyquistDecayTime = fundDecayTime * 0.1;

	_strum = new Ostrum(SR, freq, squish, fundDecayTime, nyquistDecayTime);

	return nSamps();
}
Example #6
0
void FMINST::doupdate()
{
   double p[10];
   update(p, 10);

	amp = p[2];
	if (amptable)
		amp *= tablei(currentFrame(), amptable, amptabs);

	if (p[3] != carfreqraw) {
		carfreqraw = p[3];
		if (carfreqraw < 15.0)
			carfreq = cpspch(carfreqraw);
		else
			carfreq = carfreqraw;
	}
	if (p[4] != modfreqraw) {
		modfreqraw = p[4];
		if (modfreqraw < 15.0)
			modfreq = cpspch(modfreqraw);
		else
			modfreq = modfreqraw;
		modosc->setfreq(modfreq);
	}

	minindex = p[5];
	float maxindex = p[6];
	if (minindex > maxindex) {		// swap if wrong order
		float tmp = minindex;
		minindex = maxindex;
		maxindex = tmp;
	}
	float guide;
	if (nargs > 9)			// guide pfield is present
		guide = p[9];
	else                 // backward-compatible gen table
		guide = tablei(currentFrame(), indexenv, indtabs);
	float index = minindex + ((maxindex - minindex) * guide);
	peakdev = index * modfreq;

	pan = p[7];
}
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);
}
Example #8
0
void WAVY::doupdate()
{
	double p[10];
	update(p, 10, 1 << 2 | 1 << 3 | 1 << 4 | 1 << 5 | 1 << 6 | 1 << 7 | 1 << 9);

	_amp = p[2];

	if (p[3] != _freqAraw) {
		_freqAraw = p[3];
		_freqA = (_freqAraw < 15.0) ? cpspch(_freqAraw) : _freqAraw;
		_oscilA->setfreq(_freqA);
		if (p[4] == 0.0) {
			_freqB = _freqA;
			_oscilB->setfreq(_freqB);
		}
	}

	if (p[4] != 0.0 && p[4] != _freqBraw) {
		_freqBraw = p[4];
		_freqB = (_freqBraw < 15.0) ? cpspch(_freqBraw) : _freqBraw;
		_oscilB->setfreq(_freqB);
	}

	if (p[5] != _phaseOffset) {
		_phaseOffset = p[5];
		// Get current phase of oscilA; offset oscilB phase from this by
		// _phaseOffset, in units relative to wavetable lengths.  We try to 
		// handle the case where the two freqs are different.
		const int lenB = _oscilB->getlength();
		const double phaseA = _oscilA->getphase() / _oscilA->getlength();
		const double freqscale = _freqB / _freqA;
		double phase = (phaseA + (_phaseOffset * freqscale)) * lenB;
		while (phase >= double(lenB))
			phase -= double(lenB);
		_oscilB->setphase(phase);
	}
	_pan = (_nargs > 9) ? p[9] : 0.5f;
}
Example #9
0
int
main(int argc, char *argv[])
{
  int i;

  if(argc == 1) {
    printf("you must specify pitch in 8ve.pc form\n");
    exit(0);
  }
  for(i=1; i< argc; i++)
    printf("%f = %f\n",atof(argv[i]),cpspch(atof(argv[i])));

  return 0;
}
Example #10
0
void STRUM2::doupdate()
{
	double p[7];
	update(p, 7, 1 << 2 | 1 << 3 | 1 << 6);

	_amp = p[2];

	if (p[3] != _rawfreq) {
		_rawfreq = p[3];
		float freq = (_rawfreq < 15.0) ? cpspch(_rawfreq) : _rawfreq;
		_strum->setfreq(freq);
	}

	_pan = (_nargs > 6) ? p[6] : 0.5;           // default is .5
}
Example #11
0
void WAVETABLE::doupdate()
{
    double p[5];
    update(p, 5, 1 << 2 | 1 << 3 | 1 << 4);

    amp = p[2];
    if (amptable)
        amp *= tablei(currentFrame(), amptable, amptabs);

    if (p[3] != freqraw) {
        freqraw = p[3];
        float freq = (freqraw < 15.0) ? cpspch(freqraw) : freqraw;
        osc->setfreq(freq);
    }

    spread = p[4];
}
Example #12
0
int WAVETABLE::init(double p[], int n_args)
{
    float outskip = p[0];
    float dur = p[1];

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

    initamp(dur, p, 2, AMP_GEN_SLOT);

    freqraw = p[3];
    float freq;
    if (freqraw < 15.0)
        freq = cpspch(freqraw);
    else
        freq = freqraw;

    spread = p[4];

    wavetable = NULL;
    int tablelen = 0;
    if (n_args > 5)		// handle table coming in as optional p5 TablePField
        wavetable = (double *) getPFieldTable(5, &tablelen);
    if (wavetable == NULL) {
        wavetable = floc(WAVET_GEN_SLOT);
        if (wavetable)
            tablelen = fsize(WAVET_GEN_SLOT);
        else {
            rtcmix_advise("WAVETABLE", "No 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));
        }
    }
    if (tablelen > 32767)
        return die("WAVETABLE", "wavetable must have fewer than 32768 samples.");

    osc = new Ooscili(SR, freq, wavetable, tablelen);

    return nSamps();
}
void WAVESHAPE::doupdate()
{
	double p[10];
	update(p, 10, kFreq | kMinIndex | kMaxIndex | kAmp | kPan | kIndex);

	if (rawfreq != p[2]) {
		rawfreq = p[2];
		float freq = rawfreq;
		if (rawfreq < 15.0)
			freq = cpspch(rawfreq);
		osc->setfreq(freq);
		setDCBlocker(freq, false);
	}

	float min_index = p[3];
	float max_index = p[4];
	if (max_index < min_index)
		max_index = min_index;

	float rawamp = p[5];
	if (ampenv)
		rawamp *= tablei(currentFrame(), ampenv, amptabs);

	spread = p[6];

	float rawindex;
	if (nargs > 9)
		rawindex = p[9];
	else
		rawindex = tablei(currentFrame(), indenv, indtabs);
	index = min_index + ((max_index - min_index) * rawindex);

	if (doampnorm)
		amp = index ? rawamp / index : 0.0;
	else
		amp = rawamp;
}
Example #14
0
void WIGGLE::doupdate()
{
   double p[14];
   update(p, 14, 1 << 2 | 1 << 3 | 1 << 8 | 1 << 9 | 1 << 10 | 1 << 11
                                                   | 1 << 12 | 1 << 13);

   amp = p[2];
   if (amp_table)
      amp *= amp_table->tick(currentFrame(), 1.0);

   if (p[3] != car_freq_raw) {
      car_freq_raw = p[3];
      if (car_freq_raw < 15.0f)
         base_car_freq = cpspch(car_freq_raw);
      else
         base_car_freq = car_freq_raw;
   }

   // back-compat for gliss gen function
   if (cargliss_table) {
      float gliss = cargliss_table->tick(currentFrame(), 1.0);
      gliss = cpsoct(10.0 + gliss) / cpsoct10;
      car_freq = base_car_freq * gliss;
   }
   else
      car_freq = base_car_freq;

   if (depth_type != NoModOsc) {
      // guaranteed to have either the gen or the pfield
      mod_freq = modfreq_table ? modfreq_table->tick(currentFrame(), 1.0)
                                                                     : p[10];
      if (mod_freq < 0.0f)     // negative value acts as ratio flag
         mod_freq *= -car_freq;

      // guaranteed to have either the gen or the pfield
      mod_depth = moddepth_table ? moddepth_table->tick(currentFrame(), 1.0)
                                                                     : p[11];
      if (depth_type == CarPercent)
         mod_depth *= 0.01f;
   }

   if (filter_type != NoFilter) {
      // guaranteed to have either the gen or the pfield
      float cf = filtcf_table ? filtcf_table->tick(currentFrame(), 1.0) : p[12];
      if (cf != cf_raw) {
         if (cf <= 0.0f)
            cf = 1.0f;
         if (cf > nyquist)
            cf = nyquist;
         if (filter_type == LowPass) {
            for (int i = 0; i < nfilts; i++)
               filt[i]->setLowPass(cf);
         }
         else if (filter_type == HighPass) {
            for (int i = 0; i < nfilts; i++)
               filt[i]->setHighPass(cf);
         }
         cf_raw = cf;
      }
   }

   pan = pan_table ? pan = pan_table->tick(currentFrame(), 1.0) : p[13];

#ifdef DEBUG1
   printf("amp=%f cfreq=%f mfreq=%f mdpth=%f pan=%f\n",
            amp, car_freq, mod_freq, mod_depth, pan);
#endif
}
Example #15
0
double m_diapason(float p[], int n_args, double pp[])
{
   diap = (pp[0]<18.0) ? cpspch(pp[0]) : pp[0];
   octaveOffset = (n_args>1) ? pp[1] : 8.0;
   return 0;
}
Example #16
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();
}
int WAVESHAPE::init(double p[], int n_args)
{
	nargs = n_args;
	float outskip = p[0];
	float dur = p[1];
	rawfreq = p[2];
	doampnorm = n_args > 10 ? (bool) p[10] : true;

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

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

	float freq = rawfreq;
	if (rawfreq < 15.0)
		freq = cpspch(rawfreq);

	osc = new Ooscili(SR, freq, waveform, tablelen);

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

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

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

	setDCBlocker(freq, true);		// initialize dc blocking filter

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

	return nSamps();
}
int LPCPLAY::localInit(double p[], int n_args)
{
   int i;

	if (!n_args || n_args < 6)
		return die("LPCPLAY",
				   "p[0]=starting time, p[1]=duration, p[2]=amp, p[3]=pitch, p[4]=frame1, p[5]=frame2, [ p[6]=warp p7=resoncf, p8=resonbw [ p9--> pitchcurves ] ]\n");

   /* Store pfields in variables, to allow for easy pfield renumbering.
      You should retain the RTcmix numbering convention for the first
      4 pfields: outskip, inskip, dur, amp; or, for instruments that 
      take no input: outskip, dur, amp.
   */
	float outskip = p[0];
	float ldur = p[1];
	_amp = p[2];
	_pitch = p[3];

	int startFrame = (int) p[4];
	int endFrame = (int) p[5];
	int frameCount = endFrame - startFrame + 1;

	if (frameCount <= 0)
		return die("LPCPLAY", "Ending frame must be > starting frame.");

	_warpFactor = p[6];	// defaults to 0

	// Duration can be calculated from frame count

	const float defaultFrameRate = 112.0;

	ldur = (ldur > 0.) ? ldur : (frameCount/defaultFrameRate);

   /* Tell scheduler when to start this inst. 
   */
	if (rtsetoutput(outskip, ldur, this) == -1)
		return DONT_SCHEDULE;

	_envFun = floc(ENV_SLOT);
	sbrrand(1);

	// Pull all the current configuration information out of the environment.
	
	GetLPCStuff(&_highthresh,
				&_lowthresh,
				&_thresh,
				&_randamp,
				&_unvoiced_rate,
				&_risetime, 
				&_decaytime,
				&_cutoff);
					   
	GetConfiguration(&_maxdev,
					 &_perperiod,
					 &_hnfactor,
					 &_autoCorrect);
	
	// Pitch table
	_pchvals = new double[frameCount];

	// Finish the initialization
	
	float *cpoint = _coeffs + 4;
	evset(SR, getdur(), _risetime, _decaytime, ENV_SLOT, _evals);

	_frames = frameCount;
	_frame1 = startFrame;
	for (i = startFrame; i <= endFrame; ++i) {
		float findex = i;
		if (_dataSet->getFrame(findex, _coeffs) < 0)
			break;
		_pchvals[i - startFrame] = (_coeffs[PITCH] ? _coeffs[PITCH] : 256.);
		/* just in case I am using datasets with no pitch value
			stored */
	}
	float actualweight = weight(startFrame, endFrame, _thresh);
	if (!actualweight)
		actualweight = cpspch(_pitch);
	// Transpose relative amount using input with +-0.01 == +-1 semitone
	if (ABS(_pitch) < 1.0)
		_transposition = pow(2.0,(_pitch/.12));
	// Transpose relative amount using input as new center in hz
	else if (_pitch > 20)
		_transposition = _pitch/actualweight;
	// Transpose using input as new center in octave pt p.c.
	else if (_pitch > 0)
		_transposition = cpspch(_pitch)/actualweight;
	else if (_pitch < -20)
		_transposition = -_pitch;  /* flat pitch in hz */
	else
		_transposition = cpspch(-_pitch);  /* flat pitch in octave pt */

	if (n_args <= _datafields && _pitch > 0) {
		rtcmix_advise("LPCPLAY", "Overall transp factor: %f, weighted av. pitch = %g Hz",
			   _transposition, actualweight);
		if (_maxdev) 
			readjust(_maxdev,_pchvals,startFrame,endFrame,_thresh,actualweight);
		for (i=startFrame; i<=endFrame; ++i) {
			_pchvals[i - startFrame] *= _transposition;
		}
	}
	else {
		int lastfr=_frame1;
		float transp, lasttr=_transposition;
		for (int nn = _datafields-1; nn < n_args; nn+=2) {
			if (ABS(p[nn+1]) < 1.) {
				transp = pow(2.0,(p[nn+1]/.12));
			}
			else {
				transp = cpspch(ABS(p[nn+1])) / 
					weight((float)lastfr,(p[nn]+1.),_thresh);
			}
			float tranincr=(transp-lasttr)/(p[nn]-lastfr);
			transp=lasttr;
			for (i=lastfr;i<(int)p[nn];i++) {
				_pchvals[i-_frame1]*=transp;
				transp+=tranincr;
			}
			lastfr = (int) p[nn];
			lasttr = transp;
		}
		if (p[n_args-2] < (float) endFrame) {
			/* if last frame in couplets wasn't last frame in batch,
			   use base value from there to the end */
			transp = _transposition;
			for (i=lastfr; i<endFrame; ++i)
				_pchvals[i-startFrame] *= transp;
		}
	}
	tableset(SR, getdur(), frameCount, _tblvals);
//	actualweight = weight(startFrame,endFrame,_thresh);
	float actualcps = cpspch(ABS(_pitch));
	
	/* note, dont use this feature unless pitch is specified in p[3]*/
	
	_sineFun = floc(SINE_SLOT);
	_reson_is_on = p[7] ? true : false;
	_cf_fact = p[7];
	_bw_fact = p[8];
	_frameno = _frame1;	/* in case first frame is unvoiced */

#ifdef MAXMSP
// see note above
	CLASSBRADSSTUPIDUNVOICEDFLAG = BRADSSTUPIDUNVOICEDFLAG;
#endif

	return 0;
}