Exemplo n.º 1
0
/* ------------------------------------------------------------- post_init -- */
int FOLLOWBUTTER :: post_init(double p[], int n_args)
{
   type = getFiltType(true);
   if (type == FiltInvalid)
      return die(instname(), "Filter type must be \"lowpass\", \"highpass\", "
                             "\"bandpass\", or \"bandreject\".");

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

   if (type == BandPass || type == BandReject) {
      if (n_args < 13) {   // no p12 filter bandwidth PField, must use gen table
         double *function = floc(2);
         if (function == NULL)
            return die(instname(), "Either use the filter bandwidth pfield "
                        "(p12) or make an old-style gen function in slot 2.");
         int len = fsize(2);
         bwtable = new TableL(SR, getdur(), function, len);
      }
   }

   return 0;
}
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;
}