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; );
single XTANH( single *arg ) { //=========================== return( TANH( *arg ) ); }
static int32_t nlfilt2(CSOUND *csound, NLFILT *p) { MYFLT *ar; uint32_t offset = p->h.insdshead->ksmps_offset; uint32_t early = p->h.insdshead->ksmps_no_end; uint32_t n, nsmps = CS_KSMPS; int32_t point = p->point; int32_t nm1 = point; int32_t nm2 = point - 1; int32_t nmL; MYFLT ynm1, ynm2, ynmL; MYFLT a = *p->a, b = *p->b, d = *p->d, C = *p->C; MYFLT *in = p->in; MYFLT *fp = (MYFLT*) p->delay.auxp; MYFLT L = *p->L; MYFLT maxamp, dvmaxamp, maxampd2; if (UNLIKELY(fp == NULL)) goto err1; /* RWD fix */ ar = p->ar; /* L is k-rate so need to check */ if (L < FL(1.0)) L = FL(1.0); else if (L >= MAX_DELAY) { L = (MYFLT) MAX_DELAY; } nmL = point - (int32_t) (L) - 1; if (UNLIKELY(nm1 < 0)) nm1 += MAX_DELAY; /* Deal with the wrapping */ if (UNLIKELY(nm2 < 0)) nm2 += MAX_DELAY; if (UNLIKELY(nmL < 0)) nmL += MAX_DELAY; ynm1 = fp[nm1]; /* Pick up running values */ ynm2 = fp[nm2]; ynmL = fp[nmL]; nsmps = CS_KSMPS; maxamp = csound->e0dbfs * FL(1.953125); /* 64000 with default 0dBFS */ dvmaxamp = FL(1.0) / maxamp; maxampd2 = maxamp * FL(0.5); if (UNLIKELY(offset)) memset(ar, '\0', offset*sizeof(MYFLT)); if (UNLIKELY(early)) { nsmps -= early; memset(&ar[nsmps], '\0', early*sizeof(MYFLT)); } for (n=offset; n<nsmps; n++) { MYFLT yn; MYFLT out; yn = a * ynm1 + b * ynm2 + d * ynmL * ynmL - C; yn += in[n] * dvmaxamp; /* Must work in small amplitudes */ out = yn * maxampd2; /* Write output */ if (out > maxamp) out = maxampd2; else if (out < -maxamp) out = -maxampd2; ar[n] = out; if (UNLIKELY(++point == MAX_DELAY)) { point = 0; } yn = TANH(yn); fp[point] = yn; /* and delay line */ if (UNLIKELY(++nmL == MAX_DELAY)) { nmL = 0; } ynm2 = ynm1; /* Shuffle along */ ynm1 = yn; ynmL = fp[nmL]; } p->point = point; return OK; err1: return csound->PerfError(csound, &(p->h), Str("nlfilt2: not initialised")); } /* end nlfilt2(p) */