void BBlockerBuf_next_i(BBlockerBuf *unit, int inNumSamples) { // buffer access GET_BUF uint32 numInputChannels = 1; // input should be one channel. if (!bbcheckBuffer(unit, bufData, bufChannels, numInputChannels, inNumSamples)) return; // get info from unit machine &m = unit->bblocker; // thread t = m.get_thread(); float *pCOut = ZOUT(0); float *stackOut0 = ZOUT(1); float *stackOut1 = ZOUT(2); float *stackOut2 = ZOUT(3); float *stackOut3 = ZOUT(4); float *stackOut4 = ZOUT(5); float *stackOut5 = ZOUT(6); float *stackOut6 = ZOUT(7); float *stackOut7 = ZOUT(8); float freq = ZIN0(1); double phase = unit->m_phase; float freqmul = unit->m_freqMul; // get heap from buffer /* Cast bufData (float()) to u8 and put it into machine's heap. For now, I assume the buffer to be HEAP_SIZE elements (i.e. 256). Buffer items should range between 0 and 255. */ for(size_t i = 0; i < HEAP_SIZE; i++) { m.m_heap[i] = (u8) bufData[i]; } // compute samples LOOP1(inNumSamples, if (phase >= 1.f) { //printf("running: %f (%e * %f)\n", phase, ZXP(freq), freqmul); phase -= 1.f; m.run(); } phase += freq * freqmul; // printf("1: %d %d\n", m.get_thread().m_pc, m.get_thread().at(0)); // out must be written last for in place operation ZXP(pCOut) = ((float) m.get_thread().m_pc / 127.f) - 1.f; ZXP(stackOut0) = ((float) m.get_thread().at(0) / 127.f) - 1.f; ZXP(stackOut1) = ((float) m.get_thread().at(1) / 127.f) - 1.f; ZXP(stackOut2) = ((float) m.get_thread().at(2) / 127.f) - 1.f; ZXP(stackOut3) = ((float) m.get_thread().at(3) / 127.f) - 1.f; ZXP(stackOut4) = ((float) m.get_thread().at(4) / 127.f) - 1.f; ZXP(stackOut5) = ((float) m.get_thread().at(5) / 127.f) - 1.f; ZXP(stackOut6) = ((float) m.get_thread().at(6) / 127.f) - 1.f; ZXP(stackOut7) = ((float) m.get_thread().at(7) / 127.f) - 1.f; ) // write back to unit, resp. buffer for(size_t i = 0; i < HEAP_SIZE; i++) {
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 LADSPA_next( LADSPA *unit, int inNumSamples ) { if(!unit->desc) return; unit->desc->run(unit->handle, inNumSamples); int i = unit->plugin_channels; while(i<unit->requested_channels) { ZClear(inNumSamples, ZOUT(i)); i++; } }
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 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 CoupledResonator_next(CoupledResonator *unit, int inNumSamples) { // get the pointer to the output buffer float *out = ZOUT(0); float displacement1 = unit->displacement1; float displacement2 = unit->displacement2; float velocity1 = unit->velocity1; float velocity2 = unit->velocity2; float acceleration1 = unit->acceleration1; float acceleration2 = unit->acceleration2; float forceSpring1 = unit->forceSpring1; float forceSpring2 = unit->forceSpring2; float forceSpring3 = unit->forceSpring3; float mass1 = ZIN0(9); float mass2 = ZIN0(10); float b1 = ZIN0(11); float b2 = ZIN0(12); float b3 = ZIN0(13); short outputChoice = ZIN0(14); float outval; LOOP(inNumSamples, acceleration1 = (forceSpring1 - forceSpring2) / mass1; acceleration2 = (forceSpring2 + forceSpring3) / mass2; velocity1 = velocity1 + acceleration1 / SAMPLERATE; velocity2 = velocity2 + acceleration2 / SAMPLERATE; displacement1 = displacement1 + velocity1 / SAMPLERATE; displacement2 = displacement2 + velocity2 / SAMPLERATE; forceSpring1 = - b1 * displacement1; forceSpring2 = - b2 * (displacement2 - displacement1); forceSpring3 = - b3 * displacement2; switch (outputChoice) { case 0: outval = displacement1; break; case 1: outval = displacement2; break; case 2: outval = velocity1; break; case 3: outval = velocity2; break; case 4: outval = acceleration1; break; case 5: outval = acceleration2; break; default: outval = displacement1; }; ZXP(out) = outval; )
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 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 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 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 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 BLOscWithComplexSinusoid_next(BLOscWithComplexSinusoid *unit, int inNumSamples) { float *out = ZOUT(0); float freqin = ZIN0(0); int32 loHarmonics = ZIN0(1); int32 numHarmonics = ZIN0(2); float slope = ZIN0(3); float evenOddRatio = ZIN0(4); int32 hiHarmonics = loHarmonics + numHarmonics - 1; // The highest harmonic index int32 hiHarmonicsPlusOne = hiHarmonics + 1; int32 loEvenHarmonics = loHarmonics%2 == 0? loHarmonics : loHarmonics + 1; // The lowest even harmonic index int32 hiEvenHarmonics = hiHarmonics%2 == 0? hiHarmonics : hiHarmonics - 1; // The highest even harmonic index int32 hiEvenHarmonicsPlusTwo = hiEvenHarmonics + 2; int32 numEvenHarmonics = (hiEvenHarmonics - loEvenHarmonics) / 2 + 1; //The total number of even harmonics float evenOddFactor = 1 - evenOddRatio; std::complex<double> evenOddFactorC(evenOddFactor, 0); float ampFactor = 0.99<slope&&slope<1.01? numHarmonics - evenOddFactor * numEvenHarmonics:((pow(slope,loHarmonics) - pow(slope,hiHarmonicsPlusOne)) / (1 - slope)) - (evenOddFactor * (pow(slope, loEvenHarmonics) - pow(slope, hiEvenHarmonicsPlusTwo)) / (1 - pow(slope, 2))); //ampFactor will be used to normalize the output amplitude. To avoid the denominator of this calculation to be 0 when slope = 1, the different formula is used when slope falls between 0.99 and 1.01. float phaseinc = ZIN0(0) * unit->partialTheta; float currentphase = unit->currentphase; std::complex<double> baseOsc; std::complex<double> r; std::complex<double> signalC; // signal as complex number float signalR; // signal as real number std::complex<double> oneC(1,0); std::complex<double> slopeC(slope, 0); float z; LOOP(inNumSamples, baseOsc = std::exp(std::complex<double>(0, currentphase)); r = slopeC * baseOsc; signalC = (std::pow(r, loHarmonics) - std::pow(r, hiHarmonicsPlusOne))/(oneC - r) - evenOddFactorC * (std::pow(r, loEvenHarmonics) - std::pow(r, hiEvenHarmonicsPlusTwo))/(oneC - std::pow(r, 2)); signalR = signalC.real(); z = signalR/ampFactor; currentphase += phaseinc; while (currentphase >= twopi_f) currentphase -= twopi_f; ZXP(out) = z; )
void LFDClipNoise_next_k(LFDClipNoise *unit, int inNumSamples) { float *out = ZOUT(0); float freq = ZIN0(0); float level = unit->mLevel; float phase = unit->mPhase; float smpdur = SAMPLEDUR; float dphase = smpdur * freq; RGET LOOP1(inNumSamples, phase -= dphase; if (phase < 0) { phase = sc_wrap(phase, 0.f, 1.f); level = fcoin(s1,s2,s3); } ZXP(out) = level; )
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 RedPhasor_next_kk(RedPhasor *unit, int inNumSamples) { float *out= ZOUT(0); float in= ZIN0(0); float rate= sc_max(0, ZIN0(1)); double start= ZIN0(2); double end= ZIN0(3); float loop= ZIN0(4); float previn= unit->m_previn; double level= unit->mLevel; if((previn<=0.f)&&(in>0.f)) { level= start; } if(loop<=0.f) { //kk off if(end<start) { LOOP(inNumSamples, ZXP(out)= level; level-= rate; level= sc_clip(level, end, start); ); } else {
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 LFDNoise3_next_k(LFDNoise3 *unit, int inNumSamples) { float *out = ZOUT(0); float freq = ZIN0(0); float a = unit->mLevelA; float b = unit->mLevelB; float c = unit->mLevelC; float d = unit->mLevelD; float phase = unit->mPhase; float dphase = freq * SAMPLEDUR; RGET LOOP1(inNumSamples, phase -= dphase; 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 AverageOutput_next( AverageOutput *unit, int inNumSamples ) { int i; float *in = IN(0); float *out = ZOUT(0); float trig = ZIN0(1); float prev_trig = unit->prev_trig; double average = unit->average; uint32 count = unit->count; if(prev_trig <= 0. && trig > 0.) { average = 0.; count = 0; } for (i=0; i<inNumSamples; ++i) { average = ((count * average) + *(in+i)) / (count + 1); ++count; ZXP(out) = average; } unit->prev_trig = trig; unit->count = count; unit->average = average; }
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 ArneodoCoulletTresser_next(ArneodoCoulletTresser *unit, int inNumSamples) { float *xout = ZOUT(0); float *yout = ZOUT(1); float *zout = ZOUT(2); float freq = ZIN0(0); double alpha = ZIN0(1); double h = ZIN0(2); double x0 = ZIN0(3); double y0 = ZIN0(4); double z0 = ZIN0(5); double xn = unit->xn; double yn = unit->yn; double zn = unit->zn; float counter = unit->counter; double xnm1 = unit->xnm1; double ynm1 = unit->ynm1; double znm1 = unit->znm1; double frac = unit->frac; float samplesPerCycle; double slope; if(freq < unit->mRate->mSampleRate){ samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); slope = 1.f / samplesPerCycle; } else { samplesPerCycle = 1.f; slope = 1.f; } // reset if start values change if((unit->x0 != x0) || (unit->y0 != y0) || (unit->z0 != z0)){ xnm1 = xn; ynm1 = yn; znm1 = zn; unit->x0 = xn = x0; unit->y0 = yn = y0; unit->z0 = zn = z0; } double dx = xn - xnm1; double dy = yn - ynm1; double dz = zn - znm1; for (int i=0; i<inNumSamples; ++i) { if(counter >= samplesPerCycle){ counter -= samplesPerCycle; frac = 0.f; xnm1 = xn; ynm1 = yn; znm1 = zn; double k1x, k2x, k3x, k4x, k1y, k2y, k3y, k4y, k1z, k2z, k3z, k4z, kxHalf, kyHalf, kzHalf; // 4th order Runge-Kutta approximate solution for differential equations k1x = h * (xnm1 * (1.1 - xnm1 / 2 - ynm1 / 2 - znm1 / 10)); k1y = h * (ynm1 * (-0.5 + xnm1 / 2 + ynm1 / 10 - znm1 / 10)); k1z = h * (znm1 * (alpha + 0.2 - alpha * xnm1 - ynm1 / 10 - znm1 / 10)); kxHalf = k1x * 0.5; kyHalf = k1y * 0.5; kzHalf = k1z * 0.5; k2x = h * ((xnm1 + kxHalf) * (1.1 - (xnm1 + kxHalf) / 2 - (ynm1 + kyHalf) / 2 - (znm1 + kzHalf) / 10)); k2y = h * ((ynm1 + kyHalf) * (-0.5 + (xnm1 + kxHalf) / 2 + (ynm1 + kyHalf) / 10 - (znm1 + kzHalf) / 10)); k2z = h * ((znm1 + kzHalf) * (alpha + 0.2 - alpha * (xnm1 + kxHalf) - (ynm1 + kyHalf) / 10 - (znm1 + kzHalf) / 10)); kxHalf = k2x * 0.5; kyHalf = k2y * 0.5; kzHalf = k2z * 0.5; k3x = h * ((xnm1 + kxHalf) * (1.1 - (xnm1 + kxHalf) / 2 - (ynm1 + kyHalf) / 2 - (znm1 + kzHalf) / 10)); k3y = h * ((ynm1 + kyHalf) * (-0.5 + (xnm1 + kxHalf) / 2 + (ynm1 + kyHalf) / 10 - (znm1 + kzHalf) / 10)); k3z = h * ((znm1 + kzHalf) * (alpha + 0.2 - alpha * (xnm1 + kxHalf) - (ynm1 + kyHalf) / 10 - (znm1 + kzHalf) / 10)); k4x = h * ((xnm1 + k3x) * (1.1 - (xnm1 + k3x) / 2 - (ynm1 + k3y) / 2 - (znm1 + k3z) / 10)); k4y = h * ((ynm1 + k3y) * (-0.5 + (xnm1 + k3x) / 2 + (ynm1 + k3y) / 10 - (znm1 + k3z) / 10)); k4z = h * ((znm1 + k3z) * (alpha + 0.2 - alpha * (xnm1 + k3x) - (ynm1 + k3y) / 10 - (znm1 + k3z) / 10)); xn = xn + (k1x + 2.0*(k2x + k3x) + k4x) * ONESIXTH; yn = yn + (k1y + 2.0*(k2y + k3y) + k4y) * ONESIXTH; zn = zn + (k1z + 2.0*(k2z + k3z) + k4z) * ONESIXTH; dx = xn - xnm1; dy = yn - ynm1; dz = zn - znm1; } counter++; ZXP(xout) = (xnm1 + dx * frac) * 0.5f; ZXP(yout) = (ynm1 + dy * frac) * 0.5f; ZXP(zout) = (znm1 + dz * frac) * 1.0f; frac += slope; } unit->xn = xn; unit->yn = yn; unit->zn = zn; unit->counter = counter; unit->xnm1 = xnm1; unit->ynm1 = ynm1; unit->znm1 = znm1; unit->frac = frac; }
void LotkaVolterra_next(LotkaVolterra *unit, int inNumSamples) { float *xout = ZOUT(0); float *yout = ZOUT(1); float freq = ZIN0(0); double a = ZIN0(1); double b = ZIN0(2); double c = ZIN0(3); double d = ZIN0(4); double h = ZIN0(5); double x0 = ZIN0(6); double y0 = ZIN0(7); double xn = unit->xn; double yn = unit->yn; float counter = unit->counter; double xnm1 = unit->xnm1; double ynm1 = unit->ynm1; double frac = unit->frac; float samplesPerCycle; double slope; if(freq < unit->mRate->mSampleRate){ samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); slope = 1.f / samplesPerCycle; } else { samplesPerCycle = 1.f; slope = 1.f; } // reset if start values change if((unit->x0 != x0) || (unit->y0 != y0)){ xnm1 = xn; ynm1 = yn; unit->x0 = xn = x0; unit->y0 = yn = y0; } double dx = xn - xnm1; double dy = yn - ynm1; for (int i=0; i<inNumSamples; ++i) { if(counter >= samplesPerCycle){ counter -= samplesPerCycle; frac = 0.f; xnm1 = xn; ynm1 = yn; double k1x, k2x, k3x, k4x, k1y, k2y, k3y, k4y, kxHalf, kyHalf; // 4th order Runge-Kutta approximate solution for differential equations k1x = h * (xnm1 * (a - b * ynm1)); k1y = h * (ynm1 * (c * xnm1 - d)); kxHalf = k1x * 0.5; kyHalf = k1y * 0.5; k2x = h * ((xnm1 + kxHalf) * (a - b * (ynm1 + kyHalf))); k2y = h * ((ynm1 + kyHalf) * (c * (xnm1 + kxHalf) - d)); kxHalf = k2x * 0.5; kyHalf = k2y * 0.5; k3x = h * ((xnm1 + kxHalf) * (a - b * (ynm1 + kyHalf))); k3y = h * ((ynm1 + kyHalf) * (c * (xnm1 + kxHalf) - d)); k4x = h * ((xnm1 + k3x) * (a - b * (ynm1 + k3y))); k4y = h * ((ynm1 + k3y) * (c * (xnm1 + k3x) - d)); xn = xn + (k1x + 2.0*(k2x + k3x) + k4x) * ONESIXTH; yn = yn + (k1y + 2.0*(k2y + k3y) + k4y) * ONESIXTH; dx = xn - xnm1; dy = yn - ynm1; } counter++; ZXP(xout) = (xnm1 + dx * frac) * 0.5f; ZXP(yout) = (ynm1 + dy * frac) * 0.5f; frac += slope; } unit->xn = xn; unit->yn = yn; unit->counter = counter; unit->xnm1 = xnm1; unit->ynm1 = ynm1; unit->frac = frac; }
void Convolution_next(Convolution *unit, int numSamples) { float *in1 = IN(0); float *in2 = IN(1); float *out1 = unit->m_inbuf1 + unit->m_pos; float *out2 = unit->m_inbuf2 + unit->m_pos; //int numSamples = unit->mWorld->mFullRate.mBufLength; // copy input Copy(numSamples, out1, in1); Copy(numSamples, out2, in2); unit->m_pos += numSamples; int insize= unit->m_insize; if (unit->m_pos & insize) { //have collected enough samples to transform next frame unit->m_pos = 0; //reset collection counter int memsize= insize*sizeof(float); // copy to fftbuf memcpy(unit->m_fftbuf1, unit->m_inbuf1, memsize); memcpy(unit->m_fftbuf2, unit->m_inbuf2, memsize); //zero pad second part of buffer to allow for convolution memset(unit->m_fftbuf1+unit->m_insize, 0, memsize); memset(unit->m_fftbuf2+unit->m_insize, 0, memsize); // do fft //in place transform for now //old Green fft code, now replaced by scfft // int log2n = unit->m_log2n; // rffts(unit->m_fftbuf1, log2n, 1, cosTable[log2n]); // rffts(unit->m_fftbuf2, log2n, 1, cosTable[log2n]); scfft_dofft(unit->m_scfft1); scfft_dofft(unit->m_scfft2); //complex multiply time float * p1= unit->m_fftbuf1; float * p2= unit->m_fftbuf2; p1[0] *= p2[0]; p1[1] *= p2[1]; //complex multiply for (int i=1; i<insize; ++i) { float real,imag; int realind,imagind; realind= 2*i; imagind= realind+1; real= p1[realind]*p2[realind]- p1[imagind]*p2[imagind]; imag= p1[realind]*p2[imagind]+ p1[imagind]*p2[realind]; p1[realind] = real; p1[imagind]= imag; } //copy second part from before to overlap memcpy(unit->m_overlapbuf, unit->m_outbuf+unit->m_insize, memsize); //inverse fft into outbuf memcpy(unit->m_outbuf, unit->m_fftbuf1, unit->m_fftsize * sizeof(float)); //in place //riffts(unit->m_outbuf, log2n, 1, cosTable[log2n]); scfft_doifft(unit->m_scfftR); } //write out samples copied from outbuf, with overlap added in float *output = ZOUT(0); float *out= unit->m_outbuf+unit->m_pos; float *overlap= unit->m_overlapbuf+unit->m_pos; for (int i=0; i<numSamples; ++i) ZXP(output) = out[i] + overlap[i]; }
memcpy(unit->m_overlapbuf, unit->m_outbuf+unit->m_insize, insize); //inverse fft into outbuf memcpy(unit->m_outbuf, unit->m_fftbuf1, unit->m_fftsize * sizeof(float)); //in place //riffts(unit->m_outbuf, log2n, 1, cosTable[log2n]); scfft_doifft(unit->m_scfftR); // DoWindowing(log2n, unit->m_outbuf, unit->m_fftsize); } //write out samples copied from outbuf, with overlap added in float *output = ZOUT(0); float *out= unit->m_outbuf+unit->m_pos; float *overlap= unit->m_overlapbuf+unit->m_pos; unit->m_prevtrig = curtrig; for (int i=0; i<numSamples; ++i) ZXP(output) = out[i] + overlap[i]; } // flawed since assumes framesize at least divides blocksize. framesize has to be power of two anyway: commenting out pending deletion //// if kernel size is smaller than server block size (note: this is not working yet... //void Convolution2_next2(Convolution2 *unit, int wrongNumSamples) //{ //
void RosslerL_next(RosslerL *unit, int inNumSamples) { float *xout = ZOUT(0); float *yout = ZOUT(1); float *zout = ZOUT(2); float freq = ZIN0(0); double a = ZIN0(1); double b = ZIN0(2); double c = ZIN0(3); double h = ZIN0(4); double x0 = ZIN0(5); double y0 = ZIN0(6); double z0 = ZIN0(7); double xn = unit->xn; double yn = unit->yn; double zn = unit->zn; float counter = unit->counter; double xnm1 = unit->xnm1; double ynm1 = unit->ynm1; double znm1 = unit->znm1; double frac = unit->frac; float samplesPerCycle; double slope; if(freq < unit->mRate->mSampleRate){ samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); slope = 1.f / samplesPerCycle; } else { samplesPerCycle = 1.f; slope = 1.f; } if((unit->x0 != x0) || (unit->y0 != y0) || (unit->z0 != z0)){ xnm1 = xn; ynm1 = yn; znm1 = zn; unit->x0 = xn = x0; unit->y0 = yn = y0; unit->z0 = zn = z0; } double dx = xn - xnm1; double dy = yn - ynm1; double dz = zn - znm1; for (int i=0; i<inNumSamples; ++i) { if(counter >= samplesPerCycle){ counter -= samplesPerCycle; frac = 0.f; xnm1 = xn; ynm1 = yn; znm1 = zn; double k1x, k2x, k3x, k4x, k1y, k2y, k3y, k4y, k1z, k2z, k3z, k4z, kxHalf, kyHalf, kzHalf; // 4th order Runge-Kutta approximate solution for differential equations k1x = - (h * (ynm1 + znm1)); k1y = h * (xnm1 + a * ynm1); k1z = h * (b + znm1 * (xnm1 - c)); kxHalf = k1x * 0.5; kyHalf = k1y * 0.5; kzHalf = k1z * 0.5; k2x = - (h * (ynm1 + kyHalf + znm1 + kzHalf)); k2y = h * (xnm1 + kxHalf + a * (ynm1 + kyHalf)); k2z = h * (b + (znm1 + kzHalf) * (xnm1 + kxHalf - c)); kxHalf = k2x * 0.5; kyHalf = k2y * 0.5; kzHalf = k2z * 0.5; k3x = - (h * (ynm1 + kyHalf + znm1 + kzHalf)); k3y = h * (xnm1 + kxHalf + a * (ynm1 + kyHalf)); k3z = h * (b + (znm1 + kzHalf) * (xnm1 + kxHalf - c)); k4x = - (h * (ynm1 + k3y + znm1 + k3z)); k4y = h * (xnm1 + k3x + a * (ynm1 + k3y)); k4z = h * (b + (znm1 + k3z) * (xnm1 + k3x - c)); xn = xn + (k1x + 2.0*(k2x + k3x) + k4x) * ONESIXTH; yn = yn + (k1y + 2.0*(k2y + k3y) + k4y) * ONESIXTH; zn = zn + (k1z + 2.0*(k2z + k3z) + k4z) * ONESIXTH; dx = xn - xnm1; dy = yn - ynm1; dz = zn - znm1; } counter++; ZXP(xout) = (xnm1 + dx * frac) * 0.5f; ZXP(yout) = (ynm1 + dy * frac) * 0.5f; ZXP(zout) = (znm1 + dz * frac) * 1.0f; frac += slope; } unit->xn = xn; unit->yn = yn; unit->zn = zn; unit->counter = counter; unit->xnm1 = xnm1; unit->ynm1 = ynm1; unit->znm1 = znm1; unit->frac = frac; }
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; );
float * zout(int index) const { const Unit * unit = this; return ZOUT(index); }