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 StrumQueue;
	strumq1->ref();
	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();
}
예제 #2
0
int MCLAR :: init(double p[], int n_args)
{
	nargs = n_args;
	Stk::setSampleRate(SR);

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

	amptable = floc(1);
	if (amptable) // the amp array has been created using makegen
		theEnv = new Ooscili(SR, 1.0/p[1], 1);

	theClar = new Clarinet(50.0); // 50 Hz is lowest freq for now
	noiseamp = p[4];
	theClar->setNoise(p[4]);
	stiff = p[6];
	theClar->setReedStiffness(p[6]);
	freq = p[3];
	theClar->noteOn(p[3], p[5]);

	pctleft = n_args > 7 ? p[7] : 0.5;                /* default is .5 */

	return nSamps();
}
예제 #3
0
파일: BUTTER.cpp 프로젝트: eriser/RTcmix-1
FiltType BUTTER :: getFiltType(bool trystring)
{
   double index = (double) currentFrame() / nSamps();
   const PField &field = getPField(4);

   // must try int first, since a valid code cast to char * will crash strncmp
   int code = field.intValue(index) - 1;  // NB: user codes are 1-based
   if ((code < LowPass || code > BandReject) && trystring) {
      const char *str = field.stringValue(index);
      code = _string_to_filtcode(str);   // -1 if no match
      if (code != -1)
         filttype_was_string = true;
   }

   FiltType filttype;
   switch (code) {
      case 0: filttype = LowPass;      break;
      case 1: filttype = HighPass;     break;
      case 2: filttype = BandPass;     break;
      case 3: filttype = BandReject;   break;
      default: filttype = FiltInvalid; break;
   }
   return filttype;
}
int WAVY::init(double p[], int n_args)
{
	if (n_args < 9)
		return usage();
	_nargs = n_args;

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

	if (rtsetoutput(outskip, dur, this) == -1)
		return DONT_SCHEDULE;
	if (outputChannels() < 1 || outputChannels() > 2)
		return die("WAVY", "Must have mono or stereo output only.");

	int wavelenA;
	double *wavetabA = (double *) getPFieldTable(6, &wavelenA);
	if (wavetabA == NULL)
		return die("WAVY", "p6 must be wavetable (use maketable)");

	int wavelenB;
	double *wavetabB = (double *) getPFieldTable(7, &wavelenB);
	if (wavetabB == NULL) {
		wavetabB = wavetabA;
		wavelenB = wavelenA;
	}

	_oscilA = new Ooscil(SR, 440.0, wavetabA, wavelenA);
	_oscilB = new Ooscil(SR, 440.0, wavetabB, wavelenB);

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

	assert(_fp != NULL || _combiner != NULL);

	return nSamps();
}
예제 #5
0
OeqType MULTEQ :: getEQType(bool trystring, int pfindex)
{
   double index = (double) currentFrame() / nSamps();
   const PField &field = getPField(pfindex);

   // must try int first, since a valid code cast to char * will crash strncmp
   int code = field.intValue(index);
   if (trystring && (code < 0 || code > 4)) {
      const char *str = field.stringValue(index);
      code = _string_to_eqcode(str);   // -1 if no match
   }

   OeqType eqtype;
   switch (code) {
      case 0: eqtype = OeqLowPass;   break;
      case 1: eqtype = OeqHighPass;  break;
      case 2: eqtype = OeqLowShelf;  break;
      case 3: eqtype = OeqHighShelf; break;
      case 4: eqtype = OeqPeaking;   break;
      case 5: eqtype = OeqBandPassCSG; break;
      default: eqtype = OeqInvalid;  break;
   }
   return eqtype;
}
예제 #6
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();
}
예제 #7
0
// --------------------------------------------------------------------- init --
int SPECTACLE2_BASE::init(double p[], int n_args)
{
	_nargs = n_args;
#ifdef NOTYET
	_print_stats = Option::printStats();
#else
	_print_stats = true;
#endif

	if (getargs(p, n_args) < 0)	// subclass gets args
		return DONT_SCHEDULE;

	// NB: subclass init will have already grabbed all pfields except these...
	const float outskip = p[0];
	const float inskip = p[1];
	_inputdur = p[2];
	_oamp = p[3];

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

	_half_fftlen = _fftlen / 2;
	_fund_anal_freq = SR / float(_fftlen);

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

	// Make sure _overlap is a power of 2 in allowed range.
	valid = false;
	for (int x = kMinOverlap; x <= kMaxOverlap; x *= 2) {
		if (_overlap == x) {
			valid = true;
			break;
		}
	}
	if (!valid)
		return die(instname(),
		           "Overlap must be a power of two between %d and %d.",
		           kMinOverlap, kMaxOverlap);

	// derive decimation from overlap
	_decimation = int(_fftlen / _overlap);

	// create this now, because subinit will need it
	_bin_groups = new int [_half_fftlen + 1];

	// subclass init -- must follow FFT and bin groups init; sets _ringdur
	if (subinit(p, n_args) < 0)
		return DONT_SCHEDULE;

	if (rtsetinput(inskip, this) == -1)
		return DONT_SCHEDULE;
	if (_inchan >= inputChannels())
		return die(instname(), "You asked for channel %d of a %d-channel input.",
		                       _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,
	// as well as to span the user's requested ring-down duration.

	_window_len_minus_decimation = _window_len - _decimation;
	_latency = _window_len_minus_decimation;
	const float latency_dur = _latency / SR;
	if (rtsetoutput(outskip, latency_dur + _inputdur + _ringdur, this) == -1)
		return DONT_SCHEDULE;
	_input_frames = int(_inputdur * SR + 0.5);	// without latency_dur
	_input_end_frame = _input_frames + _latency;

	DPRINT2("_fftlen=%d, _decimation=%d\n", _fftlen, _decimation);
	DPRINT3("_latency=%d, _input_frames=%d, ring frames = %d\n",
		_latency, _input_frames, int(_ringdur * SR + 0.5));

	return nSamps();
}
예제 #8
0
파일: LOCALIZE.cpp 프로젝트: RTcmix/RTcmix
// this is called when the instrument initializes and gets scheduled
int LOCALIZE::init(double p[], int n_args)
{
	float mult;
	int flipper;

	// set up input and output
	int returnval = rtsetoutput(p[0], p[2], this);
	if (returnval == -1) return DONT_SCHEDULE;

	returnval = rtsetinput(p[1], this);
	if (returnval == -1) return DONT_SCHEDULE;

	// get the p-field values we will use later
	_amp = p[3];

	// angle + distance from source to destination
	dist = sqrt( 
		pow((p[4]-p[7]), 2.0) +
		pow((p[5]-p[8]), 2.0) +
		pow((p[6]-p[9]), 2.0)
		);
	theta = asin((p[5] - p[8])/dist);

	headdelay = (p[10]*p[11])/1000.0; // simple assumption, sound 1000 ft/sec

	// calculate the ear delays
	flipper = 0;
	if (theta > 0.0) {
		if (p[4] - p[7] > 0.0) {
			// upper right
			mult = 1.0 - theta/M_PI_2;
		} else {
			// upper left
			mult = 1.0 - theta/M_PI_2;
			// flip
			flipper = 1;
		}
	} else {
		if (p[4] - p[7] > 0.0) {
			// lower right
			mult = 1.0 - (-theta/M_PI_2);
		} else {
			// lower left
			mult = 1.0 - (-theta/M_PI_2);
			// flip
			flipper = 1;
		}
	}

	// simple head shadow (decrease amp by 0.6 when full R or L)
	if (flipper == 0) {
		_delayR = 0;
		_delayL = mult * headdelay * SR;
		_ampL = 1.0 - (mult * 0.6);
	} else {
		_delayR = mult * headdelay * SR;
		_delayL = 0;
		_ampR = 1.0 - (mult * 0.6);
	}

	// set up delay lines
	theDelayR = new Odelayi(0.1 * SR);
	theDelayL = new Odelayi(0.1 * SR);

	// set up our sample-reading
	theIn = new Ortgetin(this);

	// check and calculate behind head (head filter)
	// simple lowpass filter for now
	_dofilt = 0;
	if ((int)p[13] == 1) {
		float filt_cutoff = 0.0;

		if (theta < 0.0) // behind us
			filt_cutoff = -theta/M_PI_2;

		// from full to 500 Hz cutoff totally behind, tracking exponentially (3)
		headfilt = new Oonepole(44100.0, 500.0 +
			pow((1.0 - filt_cutoff), 3.0)   * 21000.0);

		// cut the amplitude slightly
		_amp *= (1.0 - (filt_cutoff * 0.3));  // -theta/M_PI_2 already calculated

		_dofilt = 1;
	}


	// do amp/distance calculation
	_doampdist = 0;
	if ((int)p[14] == 1) { // linear
		float distcut;

		_mindistamp = p[15];
		_totlindist = p[16];
		if (dist < _totlindist)
			distcut = 1.0 - dist/_totlindist;
		else distcut = -1;
		if (distcut < _mindistamp) distcut = _mindistamp;
		_amp *= distcut;

		_doampdist = 1;
	}
	if ((int)p[14] == 2) { // inverse square
		float distcut;

		_mindistamp = p[15];
		if (dist*p[11] >= 1.0)
			distcut = 1.0/(dist * p[11]);
		else
			distcut = 1.0;
		if (distcut < _mindistamp) distcut = _mindistamp;
		_amp *= distcut;

		_doampdist = 2;
	}

	_branch = 0;
	_inputchan = p[12];

	return nSamps();
}
int LPCIN::run()
{
	int   n = 0;
	float out[2];        /* Space for only 2 output chans! */
	const int inchans = inputChannels();

	// Samples may have been left over from end of previous run's block
	if (_leftOver > 0)
	{
		int toAdd = min(_leftOver, framesToRun());
#ifdef debug
		printf("using %d leftover samps starting at offset %d\n",
			   _leftOver, _savedOffset);
#endif
		bmultf(&_alpvals[_savedOffset], _ampmlt, toAdd);	// Scale signal
		rtbaddout(&_alpvals[_savedOffset], toAdd);
		increment(toAdd);
		n += toAdd;
		_leftOver -= toAdd;
		_savedOffset += toAdd;
	}
	
	/* framesToRun() returns the number of sample frames -- 1 sample for each
	  channel -- that we have to write during this scheduler time slice.
	*/
	for (; n < framesToRun(); n += _counter) {
		double p[10];
		update(p, LPCIN_bw + 1);
		_amp = p[LPCIN_amp];
		_warpFactor = p[LPCIN_warp];
		_reson_is_on = p[LPCIN_cf] ? true : false;
		_cf_fact = p[LPCIN_cf];
		_bw_fact = p[LPCIN_bw];

		int loc;
		_frameno = _frame1 + ((float)(currentFrame())/nSamps()) * _frames;

#ifdef debug
		printf("\tgetting frame %g of %d (%d out of %d signal samps)\n",
			   _frameno, (int)_frames, currentFrame(), nSamps());
#endif
		if (_dataSet->getFrame(_frameno,_coeffs) == -1)
			break;

		// If requested, stabilize this frame before using
		if (_autoCorrect)
			stabilize(_coeffs, _nPoles);

		_ampmlt = _amp * _coeffs[RESIDAMP] / 10000.0;	// XXX normalize this!
		float newpch = (_coeffs[PITCH] > 0.0) ? _coeffs[PITCH] : 64.0;

		if (_coeffs[RMSAMP] < _cutoff)
			_ampmlt = 0;
		if (_reson_is_on) {
			/* Treat _cf_fact as absolute freq.
			   If _bw_fact is greater than 20, treat as absolute freq.
			   Else treat as factor (i.e., cf * factor == bw).
			*/
			float cf = _cf_fact;
			float bw = (_bw_fact < 20.0) ? cf * _bw_fact : _bw_fact;
			rszset(SR, cf, bw, 1., _rsnetc);
			/* printf("%f %f %f %f\n",_cf_fact*cps,
				_bw_fact*_cf_fact*cps,_cf_fact,_bw_fact,cps); */
		}

		float *cpoint = _coeffs + 4;
		
		if (_warpFactor != 0.0)
		{
			float warp = (_warpFactor > 1.) ? .0001 : _warpFactor;
			_ampmlt *= _warpPole.set(warp, cpoint, _nPoles);
		}
		_counter = int(((float)SR/(newpch * /*_perperiod*/ 1.0) ) * .5);
//		_counter = (RTBUFSAMPS < MAXVALS) ? RTBUFSAMPS : MAXVALS;
//		_counter = (_counter > (nSamps() - currentFrame())) ? nSamps() - currentFrame() : _counter;
		_counter = min(_counter, framesToRun() - n);
				
        if (_counter <= 0)
			break;

		rtgetin(_inbuf, this, _counter);
		// Deinterleave input
		for (int from=_inChannel, to=0; to < _counter; from += inchans, ++to)
			_buzvals[to] = _inbuf[from];

#ifdef debug
		printf("\t _buzvals[0] = %g\n", _buzvals[0]);
#endif
		if (_warpFactor) {
//			float warp = (_warpFactor > 1.) ? shift(_coeffs[PITCH],newpch,(float)SR) : _warpFactor;
			float warp = _warpFactor;
#ifdef debug
			printf("\tpch: %f newpch: %f d: %f\n",_coeffs[PITCH], newpch, warp);
#endif
			/*************
			warp = ABS(warp) > .2 ? SIGN(warp) * .15 : warp;
			***************/
			_warpPole.run(_buzvals, warp, cpoint, _alpvals, _counter);
		}
		else
		{
			ballpole(_buzvals,&_jcount,_nPoles,_past,cpoint,_alpvals,_counter);
		}
#ifdef debug
		{ int x; float maxamp=0; for (x=0;x<_counter;x++) { if (ABS(_alpvals[x]) > ABS(maxamp)) maxamp = _alpvals[x]; }
			printf("\t maxamp = %g\n", maxamp);
		}
#endif
		if (_reson_is_on)
			bresonz(_alpvals,_rsnetc,_alpvals,_counter);

		int sampsToAdd = min(_counter, framesToRun() - n);
		
//		printf("\tscaling %d samples by %g\n", sampsToAdd, _ampmlt);

		bmultf(_alpvals, _ampmlt, sampsToAdd);	// Scale signal
		
		/* Write this block to the output buffer. */
		rtbaddout(_alpvals, sampsToAdd);
		
		/* Keep track of how many sample frames this instrument has generated. */
		increment(sampsToAdd);
	}
	// Handle case where last synthesized block extended beyond framesToRun()
	if (n > framesToRun())
	{
		_leftOver = n - framesToRun();
		_savedOffset = _counter - _leftOver;
#ifdef debug
		printf("saving %d samples left over at offset %d\n", _leftOver, _savedOffset);
#endif
	}

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

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

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

	amp = p[3];

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

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

	return nSamps();
}
예제 #11
0
int GVERB::init(double pfs[], int n_args)
{
	if (rtsetoutput(pfs[0], pfs[2]+pfs[11], this) == -1)
		return DONT_SCHEDULE;
	if (outputChannels() != 2)
		return die("GVERB", "stereo output required");
	if (rtsetinput(pfs[1], this) == -1)
		return DONT_SCHEDULE;   // no input

	inputframes = pfs[2] * SR;
	inputchan = pfs[12];

	amp = pfs[3];

	float maxroomsize = 300.0f;
	float roomsize = 50.0f;
	float revtime = 7.0f;
	float damping = 0.5f;
	float spread = 15.0f;
	float inputbandwidth = 0.5f;
	float drylevel = 0.0f; //-1.9832f;
	float earlylevel = 0.0f; //-1.9832f;
	float taillevel = 0.0f;

	float ga,gb,gt;
	unsigned int i;
	int n;
	float r;
	float diffscale;
	int a,b,c,cc,d,dd,e;
	float spread1,spread2;

	// BGG max/msp heritage, params/etc. stored in this "p" struct (ty_gverb)
	p = &realp;
	// zero out the struct, to be careful
	bzero((void *)p, sizeof (ty_gverb));

	p->rate = SR;
	p->fdndamping = damping;
	p->maxroomsize = maxroomsize;
	p->roomsize = CLIP(roomsize, 0.1f, maxroomsize);
	p->revtime = revtime;
	p->drylevel = drylevel;
	p->earlylevel = earlylevel;
	p->taillevel = taillevel;

	p->maxdelay = p->rate*p->maxroomsize/340.0;
	p->largestdelay = p->rate*p->roomsize/340.0;

	/* Input damper */

	p->inputbandwidth = inputbandwidth;
	p->inputdamper = damper_make(1.0 - p->inputbandwidth);


	/* FDN section */

	p->fdndels = (ty_fixeddelay **)malloc(FDNORDER*sizeof(ty_fixeddelay *));
	if(!p->fdndels)
		return die("GVERB", "out of memory for fixeddelay ptrs");
	for(i = 0; i < FDNORDER; i++)
	{
		p->fdndels[i] = fixeddelay_make((int)p->maxdelay+1000);
		if(!p->fdndels[i])
			return die("GVERB", "out of memory for fixeddelays");
	}
	p->fdngains = (float *)malloc(FDNORDER*sizeof(float));
	p->fdnlens = (int *)malloc(FDNORDER*sizeof(int));
	if(!p->fdngains || !p->fdnlens)
		return die("GVERB", "out of memory for delay gains and lengths");

	p->fdndamps = (ty_damper **)malloc(FDNORDER*sizeof(ty_damper *));
	if(!p->fdndamps)
		return die("GVERB", "out of memory for delay amps");

	for(i = 0; i < FDNORDER; i++)
	{
		p->fdndamps[i] = damper_make(p->fdndamping);
		if(!p->fdndamps[i])
			return die("GVERB", "out of memory for delay amps 2");
	}

	ga = 60.0;
	gt = p->revtime;
	ga = pow(10.0,-ga/20.0);
	n = (int)(p->rate*gt);
	p->alpha = pow((double)ga,(double)1.0/(double)n);

	gb = 0.0;
	for(i = 0; i < FDNORDER; i++)
	{
		if (i == 0) gb = 1.000000*p->largestdelay;
		if (i == 1) gb = 0.816490*p->largestdelay;
		if (i == 2) gb = 0.707100*p->largestdelay;
		if (i == 3) gb = 0.632450*p->largestdelay;

#if 0
		p->fdnlens[i] = nearest_prime((int)gb, 0.5);
#else
		p->fdnlens[i] = (int)gb;
#endif
		// p->fdngains[i] = -pow(p->alpha,(double)p->fdnlens[i]);
		p->fdngains[i] = -powf((float)p->alpha,p->fdnlens[i]);
	}

	p->d = (float *)malloc(FDNORDER*sizeof(float));
	p->u = (float *)malloc(FDNORDER*sizeof(float));
	p->f = (float *)malloc(FDNORDER*sizeof(float));
	if(!p->d || !p->u || !p->f)
		return die("GVERB", "out of memory for other delay stuff");


	/* Diffuser section */

	diffscale = (float)p->fdnlens[3]/(210+159+562+410);
	spread1 = spread;
	spread2 = 3.0*spread;

	b = 210;
	r = 0.125541f;
	a = (int)(spread1*r);
	c = 210+159+a;
	cc = c-b;
	r = 0.854046f;
	a = (int)(spread2*r);
	d = 210+159+562+a;
	dd = d-c;
	e = 1341-d;

	p->ldifs = (ty_diffuser **)malloc(4*sizeof(ty_diffuser *));
	if(!p->ldifs)
		return die("GVERB", "out of memory for diffuser left structs");

	p->ldifs[0] = diffuser_make((int)(diffscale*b),0.75);
	p->ldifs[1] = diffuser_make((int)(diffscale*cc),0.75);
	p->ldifs[2] = diffuser_make((int)(diffscale*dd),0.625);
	p->ldifs[3] = diffuser_make((int)(diffscale*e),0.625);
	if(!p->ldifs[0] || !p->ldifs[1] || !p->ldifs[2] || !p->ldifs[3])
		return die("GVERB", "out of memory for diffuser left makes");

	b = 210;
	r = -0.568366f;
	a = (int)(spread1*r);
	c = 210+159+a;
	cc = c-b;
	r = -0.126815f;
	a = (int)(spread2*r);
	d = 210+159+562+a;
	dd = d-c;
	e = 1341-d;

	p->rdifs = (ty_diffuser **)malloc(4*sizeof(ty_diffuser *));
	if(!p->rdifs)
		return die("GVERB", "out of memory for diffuser right structs");

	p->rdifs[0] = diffuser_make((int)(diffscale*b),0.75);
	p->rdifs[1] = diffuser_make((int)(diffscale*cc),0.75);
	p->rdifs[2] = diffuser_make((int)(diffscale*dd),0.625);
	p->rdifs[3] = diffuser_make((int)(diffscale*e),0.625);
	if(!p->rdifs[0] || !p->rdifs[1] || !p->rdifs[2] || !p->rdifs[3])
		return die("GVERB", "out of memory for diffuser right makes");

	/* Tapped delay section */

	p->tapdelay = fixeddelay_make(44000);
	p->taps = (int *)malloc(FDNORDER*sizeof(int));
	p->tapgains = (float *)malloc(FDNORDER*sizeof(float));
	if(!p->tapdelay || !p->taps || !p->tapgains)
		return die("GVERB", "out of memory for taps");

	p->taps[0] = (int)(5+0.410*p->largestdelay);
	p->taps[1] = (int)(5+0.300*p->largestdelay);
	p->taps[2] = (int)(5+0.155*p->largestdelay);
	p->taps[3] = (int)(5+0.000*p->largestdelay);

	for(i = 0; i < FDNORDER; i++)
	{
		p->tapgains[i] = pow(p->alpha,(double)p->taps[i]);
	}


	// these values get set after all the init stuff
	if (pfs[4] < 1.0 || pfs[4] > maxroomsize) 
		return die("GVERB", "bogus roomsize: %f\n", pfs[4]);
	gverb_set_roomsize(p, pfs[4]); // sets p->roomsize

	if (pfs[5] < 0.1 || pfs[5] > 360.0)
		return die("GVERB", "bad revtime: %f\n", pfs[5]);
	gverb_set_revtime(p, pfs[5]);

	if (pfs[6] < 0.0 || pfs[6] > 1.0)
		return die("GVERB", "incorrect damping: %f\n", pfs[6]);
	gverb_set_damping(p, pfs[6]);

	if (pfs[7] < 0.0 || pfs[7] > 1.0)
		return die("GVERB", "input bandwith problem: %f\n", pfs[7]);
	gverb_set_inputbandwidth(p, pfs[7]);

	if (pfs[8] < -90.0 || pfs[8] > 0.0)
		return die("GVERB", "dry level wrong: %f\n", pfs[8]);
	gverb_set_drylevel(p, pfs[8]);

	if (pfs[9] < -90.0 || pfs[9] > 0.0)
		return die("GVERB", "problem with early reflection level: %f\n", pfs[9]);
	gverb_set_earlylevel(p, pfs[9]);

	if (pfs[10] < -90.0 || pfs[10] > 0.0)
		return die("GVERB", "bogus tail level: %f\n", pfs[10]);
	gverb_set_taillevel(p, pfs[10]);

	branch = 0;

	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();
}
예제 #13
0
int CONVOLVE1::init(double p[], int n_args)
{
	const float outskip = p[0];
	const float inskip = p[1];
	const float indur = p[2];
	const float impskip = p[5];
	const float impdur = p[6];
	if (impdur <= 0.0)
		return die("CONVOLVE1", "Impulse duration must be greater than zero.");
	_impgain = p[7];
	_wetpct = p[9];	// NB: used before first call to doupdate
	if (_wetpct < 0.0 || _wetpct > 1.0)
		return die("CONVOLVE1", "Wet percent must be between 0 and 1.");
	_inchan = int(p[10]);

	// Read impulse response table, and set FFT size based on this.
	_imptab = (double *) getPFieldTable(4, &_imptablen);
	if (_imptab == NULL)
		return die("CONVOLVE1", "Must store impulse response in a table.");
	_impStartIndex = int(impskip * SR + 0.5);
	if (_impStartIndex >= _imptablen)
		return die("CONVOLVE1", "Impulse start time exceeds impulse duration.");
	int impend = _impStartIndex + int(impdur * SR + 0.5);
	// NOTE: <impend> may be past end of table; we handle that in prepareImpulse.
	DPRINT2("impend=%d, _imptablen=%d\n", impend, _imptablen);
	_impframes = impend - _impStartIndex;

	_halfFFTlen = kMinFFTsize / 2;
	for ( ; _halfFFTlen < kMaxImpulseFrames; _halfFFTlen *= 2)
		if (_halfFFTlen >= _impframes)
			break;
	_fftlen = 2 * _halfFFTlen;
	DPRINT2("_impframes=%d, _halfFFTlen=%d\n", _impframes, _halfFFTlen);
	rtcmix_advise("CONVOLVE1", "Using %d impulse response frames.  FFT length is %d.",
				_impframes, _fftlen);

	if (rtsetinput(inskip, this) == -1)
		return DONT_SCHEDULE;	// no input
	if (_inchan >= inputChannels())
		return die("CONVOLVE1", "You asked for channel %d of a %d-channel input.",
										_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.

	const float latency = float(_impframes) / SR;
	const float ringdur = latency;
	if (rtsetoutput(outskip, latency + indur + ringdur, this) == -1)
		return DONT_SCHEDULE;
	if (outputChannels() > 2)
		return die("CONVOLVE1", "Must have mono or stereo output.");
	_inframes = int(indur * SR + 0.5);		// not including latency

	int winlen;
	double *wintab = (double *) getPFieldTable(8, &winlen);
	if (wintab) {
		if (winlen > 32767)	// limit for new fixed-point Ooscili
			return die("CONVOLVE1", "Window table size must be less than 32768.");
		const float freq = 1.0 / ((float) _impframes / SR);
		_winosc = new Ooscili(SR, freq, wintab, winlen);
	}

	return nSamps();
}
예제 #14
0
파일: BUTTER.cpp 프로젝트: eriser/RTcmix-1
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();
}
예제 #15
0
int PFSCHED::run()
{
	int i;

	if (firsttime == 1) {
		double tval = 0.0; // get rid of the compiler warning :-)
		if (pfbusses[pfbus].thepfield != NULL) tval = pfbusses[pfbus].val;

		pfbusses[pfbus].thepfield = PFSCHEDpfield; // this is the PField to read
		Arg targs[MAXDISPARGS];
		int nargs, lenindex;

		// if DYNTABLETOKEN is the first value in the data, it means we need
		// to construct a new table, based on the current pfield value
		// and the construction data stored in the data[] array
		if ( (*(pfbusses[pfbus].thepfield)).doubleValue(0) == DYNTABLETOKEN) {
			nargs = (int)(*(pfbusses[pfbus].thepfield)).doubleValue(1) + 2;
			lenindex = 1;
			targs[0] = "line";
			targs[1] = (*(pfbusses[pfbus].thepfield)).doubleValue(2);

			for (i = 2; i < nargs; i++) {
				// additional occurrences of DYNTABLETOKEN signal a 'curval', so
				// use the current pfield value
				if ( (*(pfbusses[pfbus].thepfield)).doubleValue(i+1) == DYNTABLETOKEN) {
					targs[i] = tval;
				} else {
					targs[i] = (*(pfbusses[pfbus].thepfield)).doubleValue(i+1);
				}
			}

			int len = targs[lenindex];
			double *data = NULL;
			data = new double[len];
			if (data == NULL) {
				die("maketable", "Out of memory.");
				return NULL;
			}

			if (_dispatch_table(targs, nargs, lenindex + 1, &data, &len) != 0) {
				delete [] data;
				return NULL;            // error message already given
			}

			TablePField *table;
			table = new TablePField(data, len);

			// replace the pfield with the newly-constructed table
			pfbusses[pfbus].thepfield = table;
		}

		pfbusses[pfbus].percent = 0.0;
		pfbusses[pfbus].dqflag = 0;
		// note the subtraction; the PField will be read for the correct duration
		pfbusses[pfbus].theincr = (SR/(float)resetval)/(double)(nSamps()-(RTBUFSAMPS+1));
		pfbusses[pfbus].drawflag = 1; // signal to start reading from the pfield
		if (set_dq_flag == 1) pfbusses[pfbus].dqflag = 1;
		firsttime = 0;
	}

	i = framesToRun();
	increment(i);

	return i;
}
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();
}
예제 #17
0
파일: MBASE.cpp 프로젝트: eriser/RTcmix-1
int MBASE::init(double p[], int n_args)
{
    int    flag, UseMikes;
    float  outskip, inskip, abs_factor, dummy;
    double R, T, dist;

    outskip = p[0];
    inskip = p[1];
    m_dur = p[2];
    if (m_dur < 0)                      /* "dur" represents timend */
        m_dur = -m_dur - inskip;

    if (rtsetinput(inskip, this) == -1) { // no input
		  return(DONT_SCHEDULE);
	}
    insamps = (int)(m_dur * SR);
	
   	inamp = p[3];

	if (inamp < 0) {
		m_paths = 1;	// Dont process secondary paths
		inamp = -inamp;
	}

    /* Get results of Minc setup calls (space, mikes_on, mikes_off, matrix) */
    if (get_setup_params(Dimensions, &m_attenParams,
						 &dummy, &abs_factor, &UseMikes, &MikeAngle,
						 &MikePatternFactor) == -1) {
		return die(name(), "You must call setup routine `space' first.");
	}

	// call inst-specific init code
    if (localInit(p, n_args) == DONT_SCHEDULE)
		  return die(name(), "localInit failed.");

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

    if (inputChannels() == 1)
       m_inchan = 0;
	
	if (outputChannels() != 4)
		return die(name(), "Output must be 4-channel (2 signal, 2 reverb feed).");
	
    /* (perform some initialization that used to be in space.c) */
    int meanLength = MFP_samps(SR, Dimensions); // mean delay length for reverb
    get_lengths(meanLength);              /* sets up delay lengths */
    set_gains();                		/* sets gains for filters */
    set_walls(abs_factor);              /* sets wall filts for move routine */


   /* flag for use of ear filters */
   m_binaural = (!UseMikes && m_dist < 0.8 && m_dist != 0.0);

   amparray = floc(1);
   if (amparray) {
      int amplen = fsize(1);
      tableset(SR, m_dur, amplen, amptabs);      /* controls input dur only */
   }
   
   /* determine extra run time for this routine before calling rtsetoutput() */
   double reflectionDur = 0.0;
   finishInit(&reflectionDur);
   
   m_branch = 0;
   
   if (rtsetoutput(outskip, m_dur + reflectionDur, this) == -1)
      return DONT_SCHEDULE;
   DBG1(printf("nsamps = %d\n", nSamps()));
   return nSamps();
}
예제 #18
0
파일: BASE.cpp 프로젝트: RTcmix/RTcmix
int BASE::init(double p[], int n_args)
{
	int	UseMikes;
	float  outskip, inskip, abs_factor, rvb_time;

	outskip = p[0];
	inskip = p[1];
	m_dur = p[2];
	if (m_dur < 0)					  /* "dur" represents timend */
		m_dur = -m_dur - inskip;

	if (rtsetinput(inskip, this) == -1) { // no input
	  return(DONT_SCHEDULE);
	}
	insamps = (int)(m_dur * SR);
	inamp = p[3];

	double Matrix[12][12];
   
	/* Get results of Minc setup calls (space, mikes_on, mikes_off, matrix) */
	if (get_setup_params(Dimensions, Matrix, &abs_factor, &rvb_time,
						 &UseMikes, &MikeAngle, &MikePatternFactor) == -1) {
	   return die(name(), "You must call setup routine `space' first.");
	}

	// call inst-specific init code
	if (localInit(p, n_args) == DONT_SCHEDULE) {
		return die(name(), "localInit failed.");
	}

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

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

	wire_matrix(Matrix);

	/* (perform some initialization that used to be in space.c) */
	int meanLength = MFP_samps(SR, Dimensions); // mean delay length for reverb
	get_lengths(meanLength);			  /* sets up delay lengths */
	set_gains(rvb_time);				/* sets gains for filters */
	set_walls(abs_factor);			  /* sets wall filts for move routine */
	set_allpass();
	set_random();					   /* sets up random variation of delays */

   /* flag for use of ear filters */
   m_binaural = (!UseMikes && m_dist < 0.8 && m_dist != 0.0);

   amparray = floc(1);
   if (amparray) {
	  int amplen = fsize(1);
	  tableset(SR, m_dur, amplen, amptabs);	  /* controls input dur only */
   }
   else
	  rtcmix_advise(name(), "Setting phrase curve to all 1's.");
   
   /* determine extra run time for this routine before calling rtsetoutput() */
   double ringdur = 0.0;
   finishInit(rvb_time, &ringdur);
   
   m_branch = 0;

   if (rtsetoutput(outskip, m_dur + ringdur, this) == -1)
	  return DONT_SCHEDULE;
   DBG1(printf("nsamps = %d\n", nSamps()));
   return nSamps();
}
예제 #19
0
int JGRAN :: init(double p[], int n_args)
{
   nargs = n_args;
   float outskip = p[0];
   float dur = p[1];
   int seed = (int) p[3];
   osctype = (p[4] == 0.0) ? AS : FM;
   randomize_phase = n_args > 5 ? (bool) p[5] : true;    // default: yes

   if (rtsetoutput(outskip, dur, this) == -1)
      return DONT_SCHEDULE;
   if (outputChannels() > 2)
      return die("JGRAN", "Output must be mono or stereo.");

   amp_table = make_table(1, dur, SR);

   // get grain envelope table
   double *function = NULL;
   int tablelen = 0;
	if (n_args > 6) {       // handle table coming in as optional p6 TablePField
		function = (double *) getPFieldTable(6, &tablelen);
	}
	if (function == NULL) {
		function = floc(2);
		if (function == NULL)
			return die("JGRAN", "Either use the grain envelope pfield (p6) "
                    "or make an old-style gen function in slot 2.");
		tablelen = fsize(2);
	}
   grainenv_oscil = new OscilL(SR, 0.0, function, tablelen);

   // get grain waveform table and create oscillator(s)
   function = NULL;
   tablelen = 0;
	if (n_args > 7) {       // handle table coming in as optional p7 TablePField
		function = (double *) getPFieldTable(7, &tablelen);
	}
	if (function == NULL) {
		function = floc(3);
		if (function == NULL) {
         tablelen = DEFAULT_WAVETABLE_SIZE;
         rtcmix_advise("JGRAN", "Using sine for grain waveform (no table 3).");
      }
      else
		   tablelen = fsize(3);
	}
   car_oscil = new OscilL(SR, 0.0, function, tablelen);
   if (osctype == FM)
      mod_oscil = new OscilL(SR, 0.0, function, tablelen);

   // create additional tables, if corresponding pfield is missing
   if (osctype == FM) {
      if (n_args <= 8) {
         modmult_table = make_table(4, dur, SR);
         if (modmult_table == NULL)
            return die("JGRAN", "Either use the modulation frequency "
                                "multiplier pfield (p8) or make an old-style "
                                "gen function in slot 4.");
      }
      if (n_args <= 9) {
         modindex_table = make_table(5, dur, SR);
         if (modindex_table == NULL)
            return die("JGRAN", "Either use the index envelope pfield (p9) "
                                "or make an old-style gen function in slot 5.");
      }
   }
   if (n_args <= 10) {
      minfreq_table = make_table(6, dur, SR);
      if (minfreq_table == NULL)
         return die("JGRAN", "Either use the min. grain frequency pfield (p10) "
                             "or make an old-style gen function in slot 6.");
   }
   if (n_args <= 11) {
      maxfreq_table = make_table(7, dur, SR);
      if (maxfreq_table == NULL)
         return die("JGRAN", "Either use the max. grain frequency pfield (p11) "
                             "or make an old-style gen function in slot 7.");
   }
   if (n_args <= 12) {
      minspeed_table = make_table(8, dur, SR);
      if (minspeed_table == NULL)
         return die("JGRAN", "Either use the min. grain speed pfield (p12) "
                             "or make an old-style gen function in slot 8.");
   }
   if (n_args <= 13) {
      maxspeed_table = make_table(9, dur, SR);
      if (maxspeed_table == NULL)
         return die("JGRAN", "Either use the max. grain speed pfield (p13) "
                             "or make an old-style gen function in slot 9.");
   }
   if (n_args <= 14) {
      minintens_table = make_table(10, dur, SR);
      if (minintens_table == NULL)
         return die("JGRAN", "Either use the min. grain intensity pfield (p14) "
                             "or make an old-style gen function in slot 10.");
   }
   if (n_args <= 15) {
      maxintens_table = make_table(11, dur, SR);
      if (maxintens_table == NULL)
         return die("JGRAN", "Either use the max. grain intensity pfield (p15) "
                             "or make an old-style gen function in slot 11.");
   }
   if (n_args <= 16) {
      density_table = make_table(12, dur, SR);
      if (density_table == NULL)
         return die("JGRAN", "Either use the grain density pfield (p16) "
                             "or make an old-style gen function in slot 12.");
   }
   if (outputChannels() == 2) {
      if (n_args <= 17) {
         pan_table = make_table(13, dur, SR);
         if (pan_table == NULL)
            return die("JGRAN", "Either use the pan pfield (p17) or make an "
                                "old-style gen function in slot 13.");
      }
      if (n_args <= 18) {
         panvar_table = make_table(14, dur, SR);
         if (panvar_table == NULL)
            return die("JGRAN", "Either use the pan randomization pfield (p18) "
                               "or make an old-style gen function in slot 14.");
      }
   }

   // seed multipliers straight from Piche/Bezkorowajny source
   durnoi = new JGNoise((unsigned int) seed * 243);
   freqnoi = new JGNoise((unsigned int) seed * 734);
   pannoi = new JGNoise((unsigned int) seed * 634);
   ampnoi = new JGNoise((unsigned int) seed * 824);
   if (randomize_phase)
      phasenoi = new JGNoise((unsigned int) seed * 951);

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

   return nSamps();
}
예제 #20
0
파일: PVOC.cpp 프로젝트: eriser/RTcmix-1
int PVOC::init(double *p, int n_args)
{
    if (!n_args || n_args < 9) {
        die("PVOC",
            "usage:\nPVOC(outskip, inskip, dur, amp, input_chan, fft_size, window_size, decim, interp, [ pitch_mult, npoles, osc threshold ])");
        return(DONT_SCHEDULE);
    }
    if (outputchans != 1) {
        die("PVOC", "Output file must have 1 channel only");
        return(DONT_SCHEDULE);
    }

    float outskip = p[0];
    float inskip = p[1];
    float dur = p[2];
    _amp = p[3];
    _inputchannel = (int) p[4];

    if (_inputchannel >= inputChannels()) {
        die("PVOC", "Requesting channel %d of a %d-channel input file",
            _inputchannel, inputChannels());
        return(DONT_SCHEDULE);
    }

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

    // pick up arguments from command line

    // Note:  all these are class vars

    R	 = (int)SR;			/* sampling rate */
    N	 = (int)p[5];		/* FFT length */
    Nw	= (int)p[6];		/* window size */
    D	 = (int)p[7];		/* decimation factor */
    I	 = (int)p[8];		/* interpolation factor */
    P	 = p[9];			/* oscillator bank pitch factor */
    Np	= (int)p[10];		/* linear prediction order */
    _oscThreshold  = p[11];		/* synthesis threshhold */

    /*	freopen( "pv.out", "w", stderr ); */
#ifdef debug
    printf("pv parameters:\n" );
    printf("R (samprate) = %d\n", R );
    printf("N (fft len) = %d\n", N );
    printf("Nw (windowlen) = %d\n", Nw );
    printf("D (decimation) = %d\n", D );
    printf("I (interpolation) = %d\n", I );
    printf("P = %g\n", P );
    printf("Np = %d\n", Np );
    printf("thresh = %g\n", _oscThreshold );
#endif

    if (I > Nw) {
        die("PVOC", "Window size must be >= interpolation factor");
        return(DONT_SCHEDULE);
    }
    TWOPI = 8.*atan(1.);
    obank = P != 0.;
    N2 = N>>1;
    Nw2 = Nw>>1;

    if (obank)
        initOscbank(N2, Np, R, Nw, I, P);

    // Factors for convert() and unconvert()

    _fundamental = (float) R / (N2 * 2);
    _convertFactor = R / (D * TWOPI);
    _unconvertFactor = TWOPI * I / R;
    _convertPhase = ::NewArray(N2 + 1);
    _unconvertPhase = ::NewArray(N2 + 1);

    // All buffer allocation done in configure()

    /*
     * initialize input and output time values (in samples)
     */
    _in = -Nw;
    if ( D )
        _on = (_in*I)/D;
    else
        _on = _in;

#ifdef debug
    printf("_in: %d  _on: %d\n", _in, _on);
#endif
    // Get pv filter if present

    ::GetFilter(&_pvFilter);
    if (_pvFilter)
        _pvFilter->ref();

    return nSamps();
}
예제 #21
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();
}
예제 #22
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();
}
예제 #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();
}
예제 #24
0
int SHAPE :: init(double p[], int n_args)
{
   nargs = n_args;
   float outskip = p[0];
   float inskip = p[1];
   float dur = p[2];
   amp = p[3];
   min_index = p[4];
   max_index = p[5];
   int ampnorm_genno = (int) p[6];
   inchan = n_args > 7 ? (int) p[7] : 0;             /* default is chan 0 */

   if (n_args < 7)
      return die("SHAPE", "Needs at least 7 arguments.");

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

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

   if (max_index < min_index)
      return die("SHAPE",
                 "Max. distortion index must not be less than min. index.");

   double *function = floc(1);
   if (function) {
      int len = fsize(1);
      amp_table = new TableL(SR, dur, function, len);
   }

   function = NULL;
   int tablelen = 0;
   if (n_args > 9) {    // handle table coming in as optional p9 TablePField
      function = (double *) getPFieldTable(9, &tablelen);
   }
   if (function == NULL) {
      function = floc(2);
      if (function == NULL)
         return die("SHAPE", "Either use the transfer function pfield (p9) "
                    "or make an old-style gen function in slot 2.");
      tablelen = fsize(2);
   }
   shaper = new WavShape();
   shaper->setTransferFunc(function, tablelen);

   function = NULL;
	if (n_args < 11) {		// no p10 guide PField, must use gen table
      function = floc(3);
      if (function) {
         int len = fsize(3);
         index_table = new TableL(SR, dur, function, len);
      }
      else
         rtcmix_advise("SHAPE", "Setting distortion index curve to all 1's.");
   }

   /* Construct the <ampnorm> WavShape object if (1) p6 is a TablePField, or
      (2) if p6 is non-zero, in which case use p6 as the gen slot for the
      amp norm function.  If p6 is zero, then don't construct <ampnorm>.
   */
   function = NULL;
   const PField &field = getPField(6);
   tablelen = field.values();
   function = (double *) field;
   if (function == NULL) {    // no table pfield
      if (ampnorm_genno > 0) {
         function = floc(ampnorm_genno);
         if (function == NULL)
            return die("SHAPE", "You specified table %d as the amplitude "
                    "normalization function, but you didn't create the table.",
                    ampnorm_genno);
         tablelen = fsize(ampnorm_genno);
      }
   }
   if (function) {
      ampnorm = new WavShape();
      ampnorm->setTransferFunc(function, tablelen);
   }

   dcblocker = new DCBlock();

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

   return nSamps();
}
/* Called by the scheduler for every time slice in which this instrument
   should run. This is where the real work of the instrument is done.
*/
int LPCPLAY::run()
{
	int   n = 0;
	float out[2];        /* Space for only 2 output chans! */

#if 0
		printf("\nLPCPLAY::run()\n");
#endif

	// Samples may have been left over from end of previous run's block
	if (_leftOver > 0)
	{
		int toAdd = min(_leftOver, framesToRun());
#ifdef debug
		printf("using %d leftover samps starting at offset %d\n",
			   _leftOver, _savedOffset);
#endif
		rtbaddout(&_alpvals[_savedOffset], toAdd);
		increment(toAdd);
		n += toAdd;
		_leftOver -= toAdd;
		_savedOffset += toAdd;
	}
	
	/* framesToRun() returns the number of sample frames -- 1 sample for each
	  channel -- that we have to write during this scheduler time slice.
	*/
	for (; n < framesToRun(); n += _counter) {
		double p[12];
		update(p, 12);
		_amp = p[2];
		_pitch = p[3];
		_transposition = ABS(_pitch);
		_warpFactor = p[6];
		_reson_is_on = p[7] ? true : false;
		_cf_fact = p[7];
		_bw_fact = p[8];
		
		int loc;
		if ( _unvoiced_rate && !_voiced )
		{
			++_frameno;	/* if unvoiced set to normal rate */
		}
		else
		{
			_frameno = _frame1 + ((float)(currentFrame())/nSamps()) * _frames;
		}
#if 0
		printf("frame %g\n", _frameno);
#endif
		if (_dataSet->getFrame(_frameno,_coeffs) == -1)
			break;
		// If requested, stabilize this frame before using
		if (_autoCorrect)
			stabilize(_coeffs, _nPoles);
			
		float buzamp = getVoicedAmp(_coeffs[THRESH]);
		_voiced = (buzamp > 0.1); /* voiced = 0 for 10:1 noise */
		float noisamp = (1.0 - buzamp) * _randamp;	/* for now */
		_ampmlt = _amp * _coeffs[RESIDAMP];
		if (_coeffs[RMSAMP] < _cutoff)
			_ampmlt = 0;
		float cps = tablei(currentFrame(),_pchvals,_tblvals);
		float newpch = cps;

		// If input pitch was specified as -X.YZ, use this as actual pitch
		if ((_pitch < 0) && (ABS(_pitch) >= 1))
			newpch = _transposition;

		if (_reson_is_on) {
			/* If _cf_fact is greater than 20, treat as absolute freq.
			   Else treat as factor.
			   If _bw_fact is greater than 20, treat as absolute freq.
			   Else treat as factor (i.e., cf * factor == bw).
			*/
			float cf = (_cf_fact < 20.0) ? _cf_fact*cps : _cf_fact;
			float bw = (_bw_fact < 20.0) ? cf * _bw_fact : _bw_fact;
			rszset(SR, cf, bw, 1., _rsnetc);
#ifdef debug
			printf("cf %g bw %g cps %g\n", cf, bw,cps);
#endif
		}
		float si = newpch * _magic;

		float *cpoint = _coeffs + 4;
		
		if (_warpFactor != 0.0)
		{
			float warp = (_warpFactor > 1.) ? .0001 : _warpFactor;
			_ampmlt *= _warpPole.set(warp, cpoint, _nPoles);
		}
		if (_hnfactor < 1.0)
		{
			buzamp *= _hnfactor;	/* compensate for gain increase */
		}
		float hn = (_hnfactor <= 1.0) ? (int)(_hnfactor*_srd2/newpch)-2 : _hnfactor;
		_counter = int(((float)SR/(newpch * _perperiod) ) * .5);
		_counter = (_counter > (nSamps() - currentFrame())) ? nSamps() - currentFrame() : _counter;
#ifdef debug
		printf("fr: %g err: %g bzamp: %g noisamp: %g pch: %g ctr: %d\n",
		 	   _frameno,_coeffs[THRESH],_ampmlt*buzamp,_ampmlt*noisamp,newpch,_counter);
#endif
        if (_counter <= 0)
			break;
		// Catch bad pitches which generate array overruns
		else if (_counter > _arrayLen) {
			rtcmix_warn("LPCPLAY", "Counter exceeded array size -- limiting.  Frame pitch: %f", newpch);
			_counter = _arrayLen;
		}

		bbuzz(_ampmlt*buzamp,si,hn,_sineFun,&_phs,_buzvals,_counter);
#ifdef debug
		printf("\t _buzvals[0] = %g\n", _buzvals[0]);
#endif
		l_brrand(_ampmlt*noisamp,_noisvals,_counter);	/* TEMPORARY */
#ifdef debug
		printf("\t _noisvals[0] = %g\n", _noisvals[0]);
#endif
		for (loc=0; loc<_counter; loc++) {
			_buzvals[loc] += _noisvals[loc];	/* add voiced and unvoiced */
		}
		if (_warpFactor) {
			float warp = (_warpFactor > 1.) ? shift(_coeffs[PITCH],newpch,(float)SR) : _warpFactor;
#ifdef debug
			printf("\tpch: %f newpch: %f d: %f\n",_coeffs[PITCH], newpch, warp);
#endif
			/*************
			warp = ABS(warp) > .2 ? SIGN(warp) * .15 : warp;
			***************/
			_warpPole.run(_buzvals, warp, cpoint, _alpvals, _counter);
		}
		else
		{
			ballpole(_buzvals,&_jcount,_nPoles,_past,cpoint,_alpvals,_counter);
		}
#ifdef debug
		{ int x; float maxamp=0; for (x=0;x<_counter;x++) { if (ABS(_alpvals[x]) > ABS(maxamp)) maxamp = _alpvals[x]; }
			printf("\t maxamp = %g\n", maxamp);
		}
#endif
		if (_reson_is_on)
			bresonz(_alpvals,_rsnetc,_alpvals,_counter);

		// Apply envelope last

		float envelope = evp(currentFrame(),_envFun,_envFun,_evals);
		bmultf(_alpvals, envelope, _counter);

		int sampsToAdd = min(_counter, framesToRun() - n);

		/* Write this block to the output buffer. */
		rtbaddout(_alpvals, sampsToAdd);
		
		/* Keep track of how many sample frames this instrument has generated. */
		increment(sampsToAdd);
	}
	// Handle case where last synthesized block extended beyond framesToRun()
	if (n > framesToRun())
	{
		_leftOver = n - framesToRun();
		_savedOffset = _counter - _leftOver;
#ifdef debug
		printf("saving %d samples left over at offset %d\n", _leftOver, _savedOffset);
#endif
	}

	return framesToRun();
}
예제 #26
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();
}
예제 #27
0
파일: VOCODE3.cpp 프로젝트: RTcmix/RTcmix
int VOCODE3::init(double p[], int n_args)
{
	_nargs = n_args;
	if (_nargs < 11)
		return usage();

	const float outskip = p[0];
	const float inskip = p[1];
	const float dur = p[2];

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

	if (outputChannels() > 2)
		return die("VOCODE3", "Output must be either mono or stereo.");
	if (inputChannels() != 2)
		return die("VOCODE3",
		"Must use 2 input channels: 'left' for carrier; 'right' for modulator.");

	_modtable_src = (double *) getPFieldTable(4, &_numfilts);
	if (_modtable_src == NULL)
		return die("VOCODE3", "p4 must have the modulator center freq. table.");
	int len;
	_cartable_src = (double *) getPFieldTable(5, &len);
	if (_cartable_src == NULL)
		return die("VOCODE3", "p5 must have the carrier center freq. table.");
	if (len != _numfilts)
		return die("VOCODE3", "Modulator and carrier center freq. tables must "
									 "be the same size.");
	_modtable_prev = new double [_numfilts];   // these two arrays inited below
	_cartable_prev = new double [_numfilts];

	_maptable_src = (double *) getPFieldTable(6, &len);
	if (_maptable_src && (len != _numfilts))
		return die("VOCODE3", "Center freq. mapping table (p6) must be the same "
									 "size as the modulator and carrier tables.");
	_maptable = new int [_numfilts];
	if (_maptable_src) {
		for (int i = 0; i < _numfilts; i++)
			_maptable[i] = int(_maptable_src[i]);
	}
	else {	// no user mapping table; make linear mapping
		for (int i = 0; i < _numfilts; i++)
			_maptable[i] = i;
	}

	_scaletable = (double *) getPFieldTable(7, &len);
	if (_scaletable && (len != _numfilts))
		return die("VOCODE3", "The carrier scaling table must be the same size "
		                      "(%d elements) as the carrier frequency table.",
		                      _numfilts);

	_modtransp = p[8];
	_cartransp = p[9];
	_modq = p[10];
	_carq = p[11];

	_lastmod = new float [_numfilts];

	_modulator_filt = new Oequalizer * [_numfilts];
	_carrier_filt = new Oequalizer * [_numfilts];
	_balancer = new Obalance * [_numfilts];

#ifdef NOTYET
	const bool print_stats = Option::printStats();
#else
	const bool print_stats = true;
#endif
	if (print_stats) {
		rtcmix_advise(NULL, "VOCODE3:  mod. CF\tcar. CF  [Hz, after transp]");
		rtcmix_advise(NULL, "          (Q=%2.1f)\t(Q=%2.1f)", _modq, _carq);
		rtcmix_advise(NULL, "          -----------------------------------------");
	}

	for (int i = 0; i < _numfilts; i++) {
		_modulator_filt[i] = new Oequalizer(SR, kBandPassType);
		_modtable_prev[i] = _modtable_src[i];
		float mfreq = updateFreq(_modtable_src[i], _modtransp);
		_modulator_filt[i]->setparams(mfreq, _modq);

		_carrier_filt[i] = new Oequalizer(SR, kBandPassType);
		_cartable_prev[i] = _cartable_src[i];
		float cfreq = updateFreq(_cartable_src[i], _cartransp);
		_carrier_filt[i]->setparams(cfreq, _carq);

		_balancer[i] = new Obalance(SR);

		_lastmod[i] = 0.0f;	// not necessary

		if (print_stats)
			rtcmix_advise(NULL, "          %7.1f\t%7.1f", mfreq, cfreq);
	}

	return nSamps();
}
예제 #28
0
파일: WIGGLE.cpp 프로젝트: RTcmix/RTcmix
int WIGGLE::init(double p[], int n_args)
{
   const float outskip = p[0];
   const float dur = p[1];
   depth_type = (n_args > 4) ? getDepthType(p[4]) : NoModOsc;
   filter_type = (n_args > 5) ? getFiltType(p[5]) : NoFilter;

   float ringdur;
   if (filter_type == NoFilter) {
      nfilts = 0;
      ringdur = 0.0f;
   }
   else {
      if (filter_type != LowPass && filter_type != HighPass)
         return die("WIGGLE", "Filter type (p5) must be 0, 1, or 2.");
      nfilts = (n_args > 6) ? int(p[6]) : 1;
      if (nfilts < 1 || nfilts > MAXFILTS)
         return die("WIGGLE",
                    "Steepness (p6) must be an integer between 1 and %d.",
                    MAXFILTS);
      if (n_args > 7)
         do_balance = bool(p[7]);
      if (do_balance) {
         balancer = new Balance(SR);
         balancer->setWindowSize(BALANCE_WINDOW_SIZE);
      }
      ringdur = 0.1f;
   }

   if (rtsetoutput(outskip, dur + ringdur, this) == -1)
      return DONT_SCHEDULE;
   if (outputChannels() < 1 || outputChannels() > 2)
      return die("WIGGLE", "Output must be mono or stereo.");

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

   double *array = floc(AMP_FUNC);
   if (array) {
      int len = fsize(AMP_FUNC);
      amp_table = new TableL(SR, dur, array, len);
   }

   int len;
   if (n_args > 8)
      carwave_array = (double *) getPFieldTable(8, &len);
   if (carwave_array == NULL) {
      carwave_array = floc(CAR_WAVE_FUNC);
      if (carwave_array == NULL)
         return die("WIGGLE", "Either use the carrier wavetable pfield (p8), "
                              "or make an old-style gen function in slot %d.",
                              CAR_WAVE_FUNC);
      len = fsize(CAR_WAVE_FUNC);
   }
   carrier = new OscilL(SR, 0.0, carwave_array, len);

   array = floc(CAR_GLISS_FUNC);
   if (array) {
      len = fsize(CAR_GLISS_FUNC);
      cargliss_table = new TableN(SR, dur, array, len);
   }

   if (depth_type != NoModOsc) {
      if (n_args > 9)
         modwave_array = (double *) getPFieldTable(9, &len);
      if (modwave_array == NULL) {
         modwave_array = floc(MOD_WAVE_FUNC);
         if (modwave_array == NULL)
            return die("WIGGLE", "Either use the modulator wavetable pfield "
                                 "(p9), or make an old-style gen function "
                                 "in slot %d.", MOD_WAVE_FUNC);
         len = fsize(MOD_WAVE_FUNC);
      }
      modulator = new OscilL(SR, 0.0, modwave_array, len);

      array = floc(MOD_FREQ_FUNC);
      if (array) {
         len = fsize(MOD_FREQ_FUNC);
         modfreq_table = new TableL(SR, dur, array, len);
      }
      else if (n_args < 11)    // no p10 mod freq
         return die("WIGGLE", "Either use the modulator frequency pfield "
                              "(p10), or make an old-style gen function in "
                              "slot %d.", MOD_FREQ_FUNC);

      array = floc(MOD_DEPTH_FUNC);
      if (array) {
         len = fsize(MOD_DEPTH_FUNC);
         moddepth_table = new TableL(SR, dur, array, len);
      }
      else if (n_args < 12)    // no p11 mod depth
         return die("WIGGLE", "Either use the modulator depth pfield "
                              "(p11), or make an old-style gen function in "
                              "slot %d.", MOD_DEPTH_FUNC);
   }

   if (filter_type != NoFilter) {
      array = floc(FILTER_CF_FUNC);
      if (array) {
         len = fsize(FILTER_CF_FUNC);
         filtcf_table = new TableL(SR, dur, array, len);
      }
      else if (n_args < 13)    // no p12 filter cf
         return die("WIGGLE", "Either use the filter cutoff frequency pfield "
                              "(p12), or make an old-style gen function in "
                              "slot %d.", FILTER_CF_FUNC);
   }

   if (outputChannels() == 2) {
      array = floc(PAN_FUNC);
      if (array) {
         len = fsize(PAN_FUNC);
         pan_table = new TableL(SR, dur, array, len);
      }
      else if (n_args < 14)    // no p13 pan
         return die("WIGGLE", "Either use the pan pfield (p13), or make an "
                              "old-style gen function in slot %d.", PAN_FUNC);
   }

   cpsoct10 = cpsoct(10.0);

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

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

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

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

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

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

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

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

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

    d = 0.0;

    return nSamps();
}