예제 #1
0
void AmplitudeMod_next(AmplitudeMod* unit, int inNumSamples)
{
	float *out = ZOUT(0);
	float *in = ZIN(0);
	float clamp = ZIN0(1);
	float relax = ZIN0(2);

	if (unit->m_clamp != clamp) {
		unit->m_clamp = clamp;
		unit->m_clampcoef = clamp == 0.0 ? 0.0 : exp(log1/(clamp * SAMPLERATE));
	}

	if (unit->m_relax != relax) {
		unit->m_relax = relax;
		unit->m_relaxcoef = relax == 0.0 ? 0.0 : exp(log1/(relax * SAMPLERATE));
	}

	float relaxcoef = unit->m_relaxcoef;
	float clampcoef = unit->m_clampcoef;
	float previn = unit->m_previn;

	float val;
	LOOP(inNumSamples,
		val = fabs(ZXP(in));
		if (val < previn) {
			val = val + (previn - val) * relaxcoef;
		} else {
			val = val + (previn - val) * clampcoef;
		}
		ZXP(out) = previn = val;
	);
예제 #2
0
void SendTrigN_next(SendTrigN *unit, int inNumSamples)
{
    const char* cmdName = "/tr";

    float *trig = ZIN(0);
    float prevtrig = unit->m_prevtrig;

    if (unit->m_values == 0)
        return;
    
    LOOP(inNumSamples, 
        float curtrig = ZXP(trig);
        if (curtrig > 0.f && prevtrig <= 0.f) {
            for (size_t i=0; i < unit->numValues(); ++i) {
                unit->m_values[i] = ZIN0(unit->valueOffset()+i);
            }
            SendNodeReply(
                &unit->mParent->mNode,
                (int)ZIN0(1),
                cmdName,
                unit->numValues(),
                unit->m_values);
        }
        prevtrig = curtrig;
    );
예제 #3
0
void Squiz_next(Squiz *unit, int inNumSamples)
{
	float *in = ZIN(0);
	float *out = ZOUT(0);

	float *buf = unit->m_buf;
	int buflen = unit->m_buflen;

	float ratio = sc_min(sc_max(ZIN0(1), 1.0f), (float)buflen); // pitch ratio; also === the sample-by-sample readback increment
	int zcperchunk = (int)ZIN0(2);

	int writepos = unit->m_writepos;
	float prevval = unit->m_prevval; // Used for checking for positivegoing zero crossings
	float readpos = unit->m_readpos; // Where in the buffer we're reading back from. Float value for accuracy, cast to uninterpolated int position though.
	int zcsofar = unit->m_zcsofar;

	float curval, outval;
	int readposi;
	for (int i=0; i < inNumSamples; ++i)
	{
		// First we read from the buffer
		readposi = (int)readpos;
		if(readposi >= buflen){
			outval = 0.f;
		}else{
			outval = buf[readposi];
			// postincrement the play-head position
			readpos += ratio;
		}

		// Next we write to the buffer
		curval = ZXP(in);
		writepos++;

		// If positive-going zero-crossing (or if buffer full), this is a new segment.
		//Print("zcsofar: %i\n", zcsofar);
		if((writepos==buflen) || (prevval<0.f && curval>=0.f && (++zcsofar >= zcperchunk))){
			writepos = 0;
			readpos = 0.f;
			zcsofar = 0;
		}
		buf[writepos] = curval;

		//Print("prevval: %g, curval: %g, on: %i, drop: %i, outof: %i, mode: %i\n", prevval, curval, on, drop, outof, mode);

		// Now output the thing we read
		ZXP(out) = outval;
		prevval = curval;
	}

	// Store state
	unit->m_writepos = writepos;
	unit->m_readpos = readpos;
	unit->m_prevval = prevval;
	unit->m_zcsofar = zcsofar;
}
void Demand_next_aa(Demand *unit, int inNumSamples)
{
	float *trig = ZIN(0);
	float *reset = ZIN(1);

	float** out = unit->m_out;
	float* prevout = unit->m_prevout;

	for (int i=0; i<unit->mNumOutputs; ++i) {
		out[i] = OUT(i);
	}

	float prevtrig = unit->m_prevtrig;
	float prevreset = unit->m_prevreset;

	//Print("Demand_next_aa %d  %g\n", inNumSamples, prevtrig);
	for (int i=0; i<inNumSamples; ++i) {
		float ztrig = ZXP(trig);
		float zreset = ZXP(reset);
		if (zreset > 0.f && prevreset <= 0.f) {
			for (int j=2; j<unit->mNumInputs; ++j) {
				RESETINPUT(j);
			}
		}
		if (ztrig > 0.f && prevtrig <= 0.f) {
			//Print("triggered\n");
			for (int j=2, k=0; j<unit->mNumInputs; ++j, ++k) {
				float x = DEMANDINPUT_A(j, i + 1);
				//printf("in  %d %g\n", k, x);
				if (sc_isnan(x)) x = prevout[k];
				else prevout[k] = x;
				out[k][i] = x;
			}
		} else {
			for (int j=2, k=0; j<unit->mNumInputs; ++j, ++k) {
				out[k][i] = prevout[k];
			}
		}
		prevtrig = ztrig;
		prevreset = zreset;
	}
}
예제 #5
0
void LPF18_next(LPF18 *unit, int nsmps)
{
  float *in = ZIN(0);
  float *out = ZOUT(0);
  float fco = ZIN0(1);
  float res = ZIN0(2);
  float dist = ZIN0(3);

  float aout = unit->aout;
  float ay1 = unit->ay1;
  float ay2 = unit->ay2;
  float lastin = unit->lastin;
  float kfcn, kp = unit->kp;
  float kp1, kp1h;


  if (fco != unit->last_fco) {
	  kfcn = 2.0f * unit->last_fco * SAMPLEDUR;
	  kp1 = kp+1.0f;
	  kp1h = 0.5f*kp1;

	  float newkfcn = 2.0f * fco * SAMPLEDUR;
	  float newkp = ((-2.7528f*newkfcn + 3.0429f)*newkfcn +
			   1.718f)*newkfcn - 0.9984f;
	  float newkp1 = kp+1.0f;
	  float newkp1h = 0.5f*kp1;
	  float kp1hinc = (newkp1h-kp1h)/nsmps;
	  float kpinc = (newkp-kp)/nsmps;
	  float kres = unit->kres;
	  float newkres = res * (((-2.7079f*newkp1 + 10.963f)*newkp1
				  - 14.934f)*newkp1 + 8.4974f);
	  float kresinc = (newkres-kres)/nsmps;
	  float value = unit->m_value;
	  float newvalue = 1.0f+(dist*(1.5f+2.0f*newkres*(1.0f-newkfcn)));
	  float valueinc = (newvalue-value)/nsmps;
	  unit->kp = newkp;
	  unit->m_value = newvalue;
	  unit->kres = newkres;
	  unit->last_fco = fco;
	  LOOP(nsmps,
	       float ax1   = lastin;
	       float ay11  = ay1;
	       float ay31  = ay2;
	       lastin  =  ZXP(in) - TANH(kres*aout);
	       ay1      = kp1h * (lastin + ax1) - kp*ay1;
	       ay2      = kp1h * (ay1 + ay11) - kp*ay2;
	       aout     = kp1h * (ay2 + ay31) - kp*aout;
	       ZXP(out) = TANH(aout*value);
	       kp1h += kp1hinc;
	       kp += kpinc;
	       kres += kresinc;
	       value += valueinc;
	       );
예제 #6
0
void PeakEQ4_next(PeakEQ4* unit, int inNumSamples)
{
  float *out = ZOUT(0);
  float *input = ZIN(0);
  float freq = ZIN0(1);
  float width = ZIN0(2);
  float gain = ZIN0(3);
  double *bc = unit->m_b;
  double *ac = unit->m_a;
  double *buf = unit->m_mem;


  if ((unit->freq!=freq)||(unit->gain!=gain)||(unit->width!=width)) {
	  double w0 = freq * 2*M_PI / SAMPLERATE;
	  double Dw = w0 * width;
	  calc_coeffs4(bc,ac,w0, Dw, gain);
  }

  LOOP(inNumSamples,
       double in = (double) ZXP(input);
       double iir;
       double iir2;
       double fir;
       iir= in-
         ac[0]*buf[3]-
         ac[1]*buf[2]-
         ac[2]*buf[1]-
         ac[3]*buf[0];
       fir= bc[0]*iir+
         bc[1]*buf[3]+
         bc[2]*buf[2]+
         bc[3]*buf[1]+
         bc[4]*buf[0];
       iir2= fir-
         ac[4]*buf[7]-
         ac[5]*buf[6]-
         ac[6]*buf[5]-
         ac[7]*buf[4];
       fir= bc[5]*iir2+
         bc[6]*buf[7]+
         bc[7]*buf[6]+
         bc[8]*buf[5]+
         bc[9]*buf[4];
       memmove(buf, buf+1, 7*sizeof(double));
       buf[3]= iir;
       buf[7]= iir2;
       ZXP(out) = (float)fir;
       )
}
void Duty_next_da(Duty *unit, int inNumSamples)
{

	float *reset = ZIN(duty_reset);

	float *out = OUT(0);
	float prevout = unit->m_prevout;
	float count = unit->m_count;
	float prevreset = unit->m_prevreset;
	float sr = (float) SAMPLERATE;

	for (int i=0; i<inNumSamples; ++i) {

		float zreset = ZXP(reset);
		if (zreset > 0.f && prevreset <= 0.f) {

			RESETINPUT(duty_level);
			RESETINPUT(duty_dur);
			count = 0.f;
		}
		if (count <= 0.f) {
			count = DEMANDINPUT_A(duty_dur, i + 1) * sr + count;
			if(sc_isnan(count)) {
				int doneAction = (int)ZIN0(duty_doneAction);
				DoneAction(doneAction, unit);
			}
			float x = DEMANDINPUT_A(duty_level, i + 1);
			//printf("in  %d\n", count);
			if(sc_isnan(x)) {
				x = prevout;
				int doneAction = (int)ZIN0(duty_doneAction);
				DoneAction(doneAction, unit);
			} else {
				prevout = x;
			}
			out[i] = x;

		} else {
			count--;
			out[i] = prevout;
		}

		prevreset = zreset;
	}

	unit->m_count = count;
	unit->m_prevreset = prevreset;
	unit->m_prevout = prevout;
}
예제 #8
0
void GlitchRHPF_next(GlitchRHPF* unit, int inNumSamples)
{
	//printf("GlitchRHPFs_next\n");

	float *out = ZOUT(0);
	float *in = ZIN(0);
	float freq = ZIN0(1);
	float reson = ZIN0(2);

	float y0;
	float y1 = unit->m_y1;
	float y2 = unit->m_y2;
	float a0 = unit->m_a0;
	float b1 = unit->m_b1;
	float b2 = unit->m_b2;

	if (freq != unit->m_freq || reson != unit->m_reson) {

		float qres = sc_max(0.001f, reson);
		float pfreq = freq * unit->mRate->mRadiansPerSample;

		float D = tan(pfreq * qres * 0.5f);
		float C = ((1.f-D)/(1.f+D));
		float cosf = cos(pfreq);

		float next_b1 = (1.f + C) * cosf;
		float next_b2 = -C;
		float next_a0 = (1.f + C + next_b1) * .25f;

		//post("%g %g %g   %g %g   %g %g %g   %g %g\n", *freq, pfreq, qres, D, C, cosf, next_b1, next_b2, next_a0, y1, y2);

		float a0_slope = (next_a0 - a0) * unit->mRate->mFilterSlope;
		float b1_slope = (next_b1 - b1) * unit->mRate->mFilterSlope;
		float b2_slope = (next_b2 - b2) * unit->mRate->mFilterSlope;
		LOOP(unit->mRate->mFilterLoops,
			 y0 = a0 * ZXP(in) + b1 * y1 + b2 * y2;
			 ZXP(out) = y0 - 2.f * y1 + y2;

			 y2 = a0 * ZXP(in) + b1 * y0 + b2 * y1;
			 ZXP(out) = y2 - 2.f * y0 + y1;

			 y1 = a0 * ZXP(in) + b1 * y2 + b2 * y0;
			 ZXP(out) = y1 - 2.f * y2 + y0;

			 a0 += a0_slope;
			 b1 += b1_slope;
			 b2 += b2_slope;
			 );
void LFDNoise0_next(LFDNoise0 *unit, int inNumSamples)
{
	float *out = ZOUT(0);
	float *freq = ZIN(0);
	float level = unit->mLevel;
	float phase = unit->mPhase;
	float smpdur = SAMPLEDUR;
	RGET

	LOOP1(inNumSamples,
		phase -= ZXP(freq) * smpdur;
		if (phase < 0) {
			phase = sc_wrap(phase, 0.f, 1.f);
			level = frand2(s1,s2,s3);
		}
		ZXP(out) = level;
	)
void Spring_next(Spring *unit, int inNumSamples)
{
	float pos = unit->m_pos;
	float vel = unit->m_vel;
	float *out = ZOUT(0); 		// out force
	float *in = ZIN(0); 		// in force
	float spring = ZIN0(1);		// spring constant
	float damping = 1.f - ZIN0(2);// damping
	float c = SAMPLEDUR;
	float rc = SAMPLERATE;
	spring = spring * c;
	LOOP1(inNumSamples,
		float force = ZXP(in) * c - pos * spring;
		vel = (force + vel) * damping;
		pos += vel;
		ZXP(out) = force * rc;
	);
예제 #11
0
void InsideOut_next(InsideOut *unit, int inNumSamples)
{
	float *in = ZIN(0);
	float *out = ZOUT(0);

	float val;
	for (int i=0; i < inNumSamples; ++i)
	{
		val = ZXP(in);
		if(val>0.f)
			ZXP(out) = 1.0f - val;
		else if(val<0.f)
			ZXP(out) = - 1.0f - val;
		else
			ZXP(out) = 0.f;
	}
}
예제 #12
0
void WaveLoss_next(WaveLoss *unit, int inNumSamples)
{
	float *in = ZIN(0);
	float *out = ZOUT(0);

	bool on = unit->m_on; // Whether the current wave segment is being output
	int pos = unit->m_pos; // Which "number" of wave segment we're on
	float prevval = unit->m_prevval; // Used for checking for positivegoing zero crossings

	int drop  = (int)ZIN0(1);
	int outof = (int)ZIN0(2);
	int mode  = (int)ZIN0(3);

	float curval;
	for (int i=0; i < inNumSamples; ++i)
	{
		curval = ZXP(in);
		// If positive-going zero-crossing, this is a new segment.
		if(prevval<0.f && curval>=0.f){

			if(++pos >= outof){
				pos = 0;
			}
			if(mode == 2){ // Random
				on = (frand(unit->mParent->mRGen->s1, unit->mParent->mRGen->s2, unit->mParent->mRGen->s3)
					>= ((float)drop / (float)outof));
			}else{ // Nonrandom
				on = (pos >= drop);
			}

		}

		//Print("prevval: %g, curval: %g, on: %i, drop: %i, outof: %i, mode: %i\n", prevval, curval, on, drop, outof, mode);

		// Now simply output... or don't...
		ZXP(out) = on ? curval : 0.f;
		prevval = curval;
	}

	// Store state
	unit->m_on = on;
	unit->m_pos = pos;
	unit->m_prevval = prevval;
}
void Demand_next_ak(Demand *unit, int inNumSamples)
{
	float *trig = ZIN(0);
	float zreset = IN0(1);

	float** out = unit->m_out;
	float *prevout = unit->m_prevout;

	for (int i=0; i<unit->mNumOutputs; ++i) {
		out[i] = OUT(i);
	}

	float prevtrig = unit->m_prevtrig;
	float prevreset = unit->m_prevreset;

	for (int i=0; i<inNumSamples; ++i) {
		float ztrig = ZXP(trig);
		if (zreset > 0.f && prevreset <= 0.f) {
			for (int j=2; j<unit->mNumInputs; ++j) {
				RESETINPUT(j);
			}
		}

		if (ztrig > 0.f && prevtrig <= 0.f) {
			for (int j=2, k=0; j<unit->mNumInputs; ++j, ++k) {
				float x = DEMANDINPUT_A(j, i + 1);
				if (sc_isnan(x)) x = prevout[k];
				else prevout[k] = x;
				out[k][i] = x;
			}

		} else {
			for (int j=2, k=0; j<unit->mNumInputs; ++j, ++k) {
				out[k][i] = prevout[k];
			}

		}
		prevtrig = ztrig;
		prevreset = zreset;
	}

	unit->m_prevtrig = prevtrig;
	unit->m_prevreset = prevreset;
}
void LFDNoise1_next(LFDNoise1 *unit, int inNumSamples)
{
	float *out = ZOUT(0);
	float *freq = ZIN(0);
	float prevLevel = unit->mPrevLevel;
	float nextLevel = unit->mNextLevel;
	float phase = unit->mPhase;
	float smpdur = SAMPLEDUR;

	RGET

	LOOP1(inNumSamples,
		phase -= ZXP(freq) * smpdur;
		if (phase < 0) {
			phase = sc_wrap(phase, 0.f, 1.f);
			prevLevel = nextLevel;
			nextLevel = frand2(s1,s2,s3);
		}
		ZXP(out) = nextLevel + ( phase * (prevLevel - nextLevel) );
	)
예제 #15
0
파일: RMS.cpp 프로젝트: LFSaw/sc3-plugins
void
RMS_next (RMS *unit, int inNumSamples)
{
  float *out = ZOUT(0);
  float *in = ZIN(0);
  float freq = ZIN0(1);
  float p = unit->p;
  float y1 = unit->m_y1;
  float lastLPF = unit->last_lpf;
  float inVal;

  if (unit->last_freq != freq) {
	  float newp = (1.f-2.f*tanf((freq/SAMPLERATE)));
	  float pinc = (newp-p)/inNumSamples;
	  unit->p=newp;
	  unit->last_freq=freq;
	  LOOP(inNumSamples,
	  	   inVal = ZXP(in);
	  	   lastLPF = (1.f-p)*(inVal*inVal)+ p*lastLPF;
	       ZXP(out) = y1 = zapgremlins(sqrt(lastLPF));
	       p += pinc;
	  );
예제 #16
0
void RedLbyl_next_a(RedLbyl *unit, int inNumSamples) {
	float *out= ZOUT(0);
	float *in= ZIN(0);
	float thresh= ZIN0(1);
	float samples= ZIN0(2);
	float prevout= unit->m_prevout;
	unsigned long counter= unit->m_counter;
	
	LOOP(inNumSamples,
		 float zout= ZXP(in);
		 if(sc_abs(zout-prevout)>thresh) {
			counter++;
			if(counter<samples) {
				zout= prevout;
			} else {
				counter= 0;
			}
		 } else {
			counter= 0;
		 }
		 prevout= zout;
		 ZXP(out)= zout;
	);
예제 #17
0
void Crest_next(Crest* unit, int inNumSamples)
{
    float *in = ZIN(0);
    float gate = ZIN0(1);

    // Get state and instance variables from the struct
    float* circbuf = unit->m_circbuf;
    int circbufpos = unit->m_circbufpos;
    int length = unit->m_length;
    float result = unit->m_result;
    bool notfullyet = unit->m_notfullyet;
    int realNumSamples = unit->m_realNumSamples;

    LOOP(realNumSamples,
         // Always add to the ringbuf, even if we're not calculating
         circbuf[circbufpos++] = std::fabs(ZXP(in));
    if(circbufpos == length) {
    circbufpos = 0U;
    if(notfullyet) {
            notfullyet = unit->m_notfullyet = false;
        }
    }
        );
void LFDNoise3_next(LFDNoise3 *unit, int inNumSamples)
{
	float *out = ZOUT(0);
	float *freq = ZIN(0);
	float a = unit->mLevelA;
	float b = unit->mLevelB;
	float c = unit->mLevelC;
	float d = unit->mLevelD;
	float phase = unit->mPhase;
	float smpdur = SAMPLEDUR;

	RGET

	LOOP1(inNumSamples,
		phase -= ZXP(freq) * smpdur;
		if (phase < 0) {
			phase = sc_wrap(phase, 0.f, 1.f);
			a = b;
			b = c;
			c = d;
			d = frand2(s1,s2,s3) * 0.8f;	// limits max interpol. overshoot to 1.
		}
		ZXP(out) = cubicinterp(1.f - phase, a, b, c, d);
	)
void DemandEnvGen_next_a(DemandEnvGen *unit, int inNumSamples)
{

	float *reset = ZIN(d_env_reset);
	float *gate = ZIN(d_env_gate);

	float *out = ZOUT(0);

	float prevreset = unit->m_prevreset;
	double level = unit->m_level;
	float phase = unit->m_phase;
	double curve = unit->m_curve;
	bool release = unit->m_release;
	bool running = unit->m_running;


	int shape = unit->m_shape;
	// printf("phase %f \n", phase);

	for (int i=0; i<inNumSamples; ++i) {

		float zreset = ZXP(reset);
		if (zreset > 0.f && prevreset <= 0.f) {
			// printf("reset: %f %f \n", zreset, unit->m_prevreset);
			RESETINPUT(d_env_level);
			if(zreset <= 1.f) {
				DEMANDINPUT_A(d_env_level, i + 1); // remove first level
			} else {
				level = DEMANDINPUT_A(d_env_level, i + 1); // jump to first level
			}

			RESETINPUT(d_env_dur);
			RESETINPUT(d_env_shape);
			release = false;
			running = true;

			phase = 0.f;

		}

		prevreset = zreset;


		if (phase <= 0.f && running) {

			// was a release?
			if(release) {

				running = false;
				release = false;
				// printf("release: %f %f \n", phase, level);
				int doneAction = (int)ZIN0(d_env_doneAction);
				DoneAction(doneAction, unit);

			} else {



				// new time

				float dur = DEMANDINPUT_A(d_env_dur, i + 1);
				// printf("dur: %f \n", dur);
				if(sc_isnan(dur)) {
					release = true;
					running = false;
					phase = MAXFLOAT;
				} else {
					phase = dur * ZIN0(d_env_timeScale) * SAMPLERATE + phase;
				}

				// new shape
				float count;
				curve = DEMANDINPUT_A(d_env_shape, i + 1);
				shape = (int)DEMANDINPUT_A(d_env_shape, i + 1);

				// printf("shapes: %i \n", shape);
				if (sc_isnan(curve)) curve = unit->m_shape;
				if (sc_isnan(shape)) shape = unit->m_shape;

				if (phase <= 1.f) {
					shape = 1; // shape_Linear
					count = 1.f;
				} else {
					count = phase;
				}
				if(dur * 0.5f < SAMPLEDUR) shape = 1;


				// new end level

				double endLevel = DEMANDINPUT_A(d_env_level, i + 1);
				// printf("levels: %f %f\n", level, endLevel);
				if (sc_isnan(endLevel)) {
					endLevel = unit->m_endLevel;
					release = true;
					phase = 0.f;
					shape = 0;
				} else  {
					endLevel = endLevel * ZIN0(d_env_levelScale) + ZIN0(d_env_levelBias);
					unit->m_endLevel = endLevel;
				}


				// calculate shape parameters

				switch (shape) {
					case shape_Step : {
						level = endLevel;
					} break;
					case shape_Linear : {
						unit->m_grow = (endLevel - level) / count;
					} break;
					case shape_Exponential : {
						unit->m_grow = pow(endLevel / level, 1.0 / count);
					} break;
					case shape_Sine : {
						double w = pi / count;

						unit->m_a2 = (endLevel + level) * 0.5;
						unit->m_b1 = 2. * cos(w);
						unit->m_y1 = (endLevel - level) * 0.5;
						unit->m_y2 = unit->m_y1 * sin(pi * 0.5 - w);
						level = unit->m_a2 - unit->m_y1;
					} break;
					case shape_Welch : {
						double w = (pi * 0.5) / count;

						unit->m_b1 = 2. * cos(w);

						if (endLevel >= level) {
							unit->m_a2 = level;
							unit->m_y1 = 0.;
							unit->m_y2 = -sin(w) * (endLevel - level);
						} else {
							unit->m_a2 = endLevel;
							unit->m_y1 = level - endLevel;
							unit->m_y2 = cos(w) * (level - endLevel);
						}
						level = unit->m_a2 + unit->m_y1;
					} break;
					case shape_Curve : {
						if (fabs(curve) < 0.001) {
							unit->m_shape = 1; // shape_Linear
							unit->m_grow = (endLevel - level) / count;
						} else {
							double a1 = (endLevel - level) / (1.0 - exp(curve));
							unit->m_a2 = level + a1;
							unit->m_b1 = a1;
							unit->m_grow = exp(curve / count);
						}
					} break;
					case shape_Squared : {
						unit->m_y1 = sqrt(level);
						unit->m_y2 = sqrt(endLevel);
						unit->m_grow = (unit->m_y2 - unit->m_y1) / count;
					} break;
					case shape_Cubed : {
						unit->m_y1 = pow(level, 0.33333333);
						unit->m_y2 = pow(endLevel, 0.33333333);
						unit->m_grow = (unit->m_y2 - unit->m_y1) / count;
					} break;
				}

			}
		}


		if(running) {
			switch (shape) {
				case shape_Step : {
				} break;
				case shape_Linear : {
					double grow = unit->m_grow;
							//Print("level %g\n", level);
						level += grow;
				} break;
				case shape_Exponential : {
					double grow = unit->m_grow;
						level *= grow;
				} break;
				case shape_Sine : {
					double a2 = unit->m_a2;
					double b1 = unit->m_b1;
					double y2 = unit->m_y2;
					double y1 = unit->m_y1;
						double y0 = b1 * y1 - y2;
						level = a2 - y0;
						y2 = y1;
						y1 = y0;
					unit->m_y1 = y1;
					unit->m_y2 = y2;
				} break;
				case shape_Welch : {
					double a2 = unit->m_a2;
					double b1 = unit->m_b1;
					double y2 = unit->m_y2;
					double y1 = unit->m_y1;
						double y0 = b1 * y1 - y2;
						level = a2 + y0;
						y2 = y1;
						y1 = y0;
					unit->m_y1 = y1;
					unit->m_y2 = y2;
				} break;
				case shape_Curve : {
					double a2 = unit->m_a2;
					double b1 = unit->m_b1;
					double grow = unit->m_grow;
						b1 *= grow;
						level = a2 - b1;
					unit->m_b1 = b1;
				} break;
				case shape_Squared : {
					double grow = unit->m_grow;
					double y1 = unit->m_y1;
						y1 += grow;
						level = y1*y1;
					unit->m_y1 = y1;
				} break;
				case shape_Cubed : {
					double grow = unit->m_grow;
					double y1 = unit->m_y1;
						y1 += grow;
						level = y1*y1*y1;
					unit->m_y1 = y1;
				} break;
				case shape_Sustain : {
				} break;
			}

			phase--;

		}

		ZXP(out) = level;
		float zgate = ZXP(gate);

		if(zgate >= 1.f) {
			unit->m_running = true;
		} else if (zgate > 0.f) {
			unit->m_running = true;
			release = true;  // release next time.
		} else {
			unit->m_running = false; // sample and hold
		}
	}

	unit->m_level = level;
	unit->m_curve = curve;
	unit->m_shape = shape;
	unit->m_prevreset = prevreset;
	unit->m_release = release;
	unit->m_phase = phase;

}
예제 #20
0
void CheckBadValues_next(CheckBadValues* unit, int inNumSamples)
{


    float *in = ZIN(0);
    float *out = ZOUT(0);
    float id = ZIN0(1);
    int post = (int) ZIN0(2);

    float samp;
    int classification;

    switch(post) {
    case 1:		// post a line on every bad value
        LOOP(inNumSamples,
             samp = ZXP(in);
             classification = sc_fpclassify(samp);
             switch (classification)
    {
    case FP_INFINITE:
        printf("Infinite number found in Synth %d, ID: %d\n", unit->mParent->mNode.mID, (int)id);
            ZXP(out) = 2;
            break;
        case FP_NAN:
            printf("NaN found in Synth %d, ID: %d\n", unit->mParent->mNode.mID, (int)id);
            ZXP(out) = 1;
            break;
        case FP_SUBNORMAL:
            printf("Denormal found in Synth %d, ID: %d\n", unit->mParent->mNode.mID, (int)id);
            ZXP(out) = 3;
            break;
        default:
            ZXP(out) = 0;
        };
            );
        break;
    case 2:
        LOOP(inNumSamples,
             samp = ZXP(in);
             classification = CheckBadValues_fold_fpclasses(sc_fpclassify(samp));
        if(classification != unit->prevclass) {
        if(unit->sameCount == 0) {
                printf("CheckBadValues: %s found in Synth %d, ID %d\n",
                       CheckBadValues_fpclassString(classification), unit->mParent->mNode.mID, (int)id);
            } else {
                printf("CheckBadValues: %s found in Synth %d, ID %d (previous %d values were %s)\n",
                       CheckBadValues_fpclassString(classification), unit->mParent->mNode.mID, (int)id,
                       (int)unit->sameCount, CheckBadValues_fpclassString(unit->prevclass)
                      );
            };
            unit->sameCount = 0;
        };
        switch (classification)
    {
    case FP_INFINITE:
        ZXP(out) = 2;
            break;
        case FP_NAN:
            ZXP(out) = 1;
            break;
        case FP_SUBNORMAL:
            ZXP(out) = 3;
            break;
        default:
            ZXP(out) = 0;
        };
        unit->sameCount++;
        unit->prevclass = classification;
            );
예제 #21
0
	const float * zin(int index) const
	{
		const Unit * unit = this;
		return ZIN(index);
	}