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; );
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; );
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; } }
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; );
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; }
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; );
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; } }
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) ); )
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; );
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; );
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; }
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; );
const float * zin(int index) const { const Unit * unit = this; return ZIN(index); }