void Echotron::init_params() { float hSR = fSAMPLE_RATE*0.5f; float tpanl, tpanr; float tmptempo; int tfcnt = 0; initparams=0; depth = ((float) (Pdepth - 64))/64.0f; dlyrange = 0.008*f_pow2(4.5f*depth); width = ((float) Pwidth)/127.0f; tmptempo = (float) Ptempo; lfo.Pfreq = lrintf(subdiv_fmod*tmptempo); dlfo.Pfreq = lrintf(subdiv_dmod*tmptempo); for(int i=0; i<Plength; i++) { // tmp_time=lrintf(fTime[i]*tempo_coeff*fSAMPLE_RATE); // if(tmp_time<maxx_size) rtime[i]=tmp_time; else rtime[i]=maxx_size; ltime[i] = rtime[i] = fTime[i]*tempo_coeff; if(fPan[i]>=0.0f) { tpanr = 1.0; tpanl = 1.0f - fPan[i]; } else { tpanl = 1.0; tpanr = 1.0f + fPan[i]; } ldata[i]=fLevel[i]*tpanl; rdata[i]=fLevel[i]*tpanr; if((tfcnt<ECHOTRON_MAXFILTERS)&&(iStages[i]>=0)) { int Freq=fFreq[i]*f_pow2(depth*4.5f); if (Freq<20.0) Freq=20.0f; if (Freq>hSR) Freq=hSR; filterbank[tfcnt].l->setfreq_and_q(Freq,fQ[i]); filterbank[tfcnt].r->setfreq_and_q(Freq,fQ[i]); filterbank[tfcnt].l->setstages(iStages[i]); filterbank[tfcnt].r->setstages(iStages[i]); filterbank[tfcnt].l->setmix (1, fLP[i] , fBP[i], fHP[i]); filterbank[tfcnt].r->setmix (1, fLP[i] , fBP[i], fHP[i]); filterbank[tfcnt].l->setmode(f_qmode); filterbank[tfcnt].r->setmode(f_qmode); tfcnt++; } } };
void Echotron::sethidamp (int Phidamp) { this->Phidamp = Phidamp; hidamp = 1.0f - (float)Phidamp / 127.1f; float fr = 20.0f*f_pow2(hidamp*10.0f); lpfl->setfreq (fr); lpfr->setfreq (fr); };
void Echotron::modulate_delay() { float lfmod, rfmod, lfol, lfor, dlfol, dlfor; float fperiod = 1.0f/param->fPERIOD; lfo.effectlfoout (&lfol, &lfor); dlfo.effectlfoout (&dlfol, &dlfor); if(Pmodfilts) { lfmod = f_pow2((lfol*width + 0.25f + depth)*4.5f); rfmod = f_pow2((lfor*width + 0.25f + depth)*4.5f); for(int i=0; i<ECHOTRON_MAXFILTERS; i++) { filterbank[i].l->setfreq(lfmod*fFreq[i]); filterbank[i].r->setfreq(rfmod*fFreq[i]); } } if(Pmoddly) { oldldmod = ldmod; oldrdmod = rdmod; ldmod = width*dlfol; rdmod = width*dlfor; // ldmod=lrintf(dlyrange*tempo_coeff*fSAMPLE_RATE*ldmod); // rdmod=lrintf(dlyrange*tempo_coeff*fSAMPLE_RATE*rdmod); ldmod=dlyrange*tempo_coeff*ldmod; rdmod=dlyrange*tempo_coeff*rdmod; interpl = (ldmod - oldldmod)*fperiod; interpr = (rdmod - oldrdmod)*fperiod; } else { oldldmod = 0.0f; oldrdmod = 0.0f; ldmod = 0.0f; rdmod = 0.0f; interpl = 0.0f; interpr = 0.0f; } };
/* * Apply the effect */ void RyanWah::out (float * smpsl, float * smpsr) { int i; float lmod, rmod; float lfol, lfor; float rms = 0.0f; lfo.effectlfoout (&lfol, &lfor); if (Pamode) { lfol *= depth; lfor *= depth; } else { lfol *= depth * 5.0f; lfor *= depth * 5.0f; } for (i = 0; i < PERIOD; i++) { efxoutl[i] = smpsl[i]; efxoutr[i] = smpsr[i]; float x = (fabsf ( sidechain_filter->filterout_s(smpsl[i] + smpsr[i]))) * 0.5f; ms1 = ms1 * ampsmooth + x * (1.0f - ampsmooth) + 1e-10f; //oldfbias -= 0.001 * oldfbias2; oldfbias = oldfbias * (1.0f - wahsmooth) + fbias * wahsmooth + 1e-10f; //smooth MIDI control oldfbias1 = oldfbias1 * (1.0f - wahsmooth) + oldfbias * wahsmooth + 1e-10f; oldfbias2 = oldfbias2 * (1.0f - wahsmooth) + oldfbias1 * wahsmooth + 1e-10f; if (Pamode) { rms = ms1 * ampsns + oldfbias2; if (rms<0.0f) rms = 0.0f; lmod = (minfreq + lfol + rms)*maxfreq; rmod = (minfreq + lfor + rms)*maxfreq; if(variq) q = f_pow2((2.0f*(1.0f-rms)+1.0f)); filterl->setq(q); filterr->setq(q); filterl->directmod(rmod); filterr->directmod(lmod); efxoutl[i] = filterl->filterout_s (smpsl[i]); efxoutr[i] = filterr->filterout_s (smpsr[i]); } }; if (!Pamode) { rms = ms1 * ampsns + oldfbias2; if(rms>0.0f) { //apply some smooth limiting rms = 1.0f - 1.0f/(rms*rms + 1.0f); } else { rms = -1.0f + 1.0f/(rms*rms + 1.0f); } if(variq) q = f_pow2((2.0f*(1.0f-rms)+1.0f)); lmod =(lfol + rms); rmod = (lfor + rms); if(lmod>1.0f) lmod = 1.0f; if(lmod<0.0f) lmod = 0.0f; if(rmod>1.0f) rmod = 1.0f; if(rmod<0.0f) rmod = 0.0f; //rms*=rms; float frl = minfreq + maxfreq*(powf(base, lmod) - 1.0f)*ibase; float frr = minfreq + maxfreq*(powf(base, rmod) - 1.0f)*ibase; centfreq = frl; //testing variable filterl->setfreq_and_q (frl, q); filterr->setfreq_and_q (frr, q); filterl->filterout (efxoutl); filterr->filterout (efxoutr); } };
/* * Effect output */ void Dflange::out (float * smpsl, float * smpsr) { int i; //deal with LFO's int tmp0, tmp1; float lfol, lfor, lmod, rmod, lmodfreq, rmodfreq, rx0, rx1, lx0, lx1; float ldif0, ldif1, rdif0, rdif1; //Difference between fractional delay and floor(fractional delay) float drA, drB, dlA, dlB; //LFO inside the loop. lfo.effectlfoout (&lfol, &lfor); lmod = lfol; if(Pzero && Pintense) rmod = 1.0f - lfol; //using lfol is intentional else rmod = lfor; if(Pintense) { //do intense stuff lmodfreq = (f_pow2(lmod*lmod*logmax)) * fdepth; //2^x type sweep for musical interpretation of moving delay line. rmodfreq = (f_pow2(rmod*rmod*logmax)) * fdepth; //logmax depends on depth rflange0 = 0.5f/rmodfreq; //Turn the notch frequency into 1/2 period delay rflange1 = rflange0 + (1.0f - foffset)/fdepth; //Set relationship of second delay line lflange0 = 0.5f/lmodfreq; lflange1 = lflange0 + (1.0f - foffset)/fdepth; rx0 = (rflange0 - oldrflange0) * period_const; //amount to add each time around the loop. Less processing of linear LFO interp inside the loop. rx1 = (rflange1 - oldrflange1) * period_const; lx0 = (lflange0 - oldlflange0) * period_const; lx1 = (lflange1 - oldlflange1) * period_const; // Now there is a fractional amount to add drA = oldrflange0; drB = oldrflange1; dlA = oldlflange0; dlB = oldlflange1; oldrflange0 = rflange0; oldrflange1 = rflange1; oldlflange0 = lflange0; oldlflange1 = lflange1; //lfo ready... if(Pzero) { for (i = 0; i < PERIOD; i++) { ldl = smpsl[i] * lpan + ldl * ffb; rdl = smpsr[i] * rpan + rdl * ffb; //LowPass Filter ldl = ldl * (1.0f - fhidamp) + oldl * fhidamp; rdl = rdl * (1.0f - fhidamp) + oldr * fhidamp; oldl = ldl + DENORMAL_GUARD; oldr = rdl + DENORMAL_GUARD; /* Here do the delay line stuff basically, dl1(dl2(smps)); ^^This runs two flangers in series so you can get a double notch */ ldl = ldelayline0->delay(ldl,dlA, 0, 1, 0) + ldelayline1->delay(ldl,drA, 0, 1, 0); rdl = rdelayline0->delay(rdl,dlB, 0, 1, 0) + rdelayline1->delay(rdl,drB, 0, 1, 0); efxoutl[i] = ldl = ldl * flrcross + rdl * frlcross; efxoutr[i] = rdl = rdl * flrcross + ldl * frlcross; // Increment LFO drA += rx0; drB += rx1; dlA += lx0; dlB += lx1; } } else { for (i = 0; i < PERIOD; i++) { ldl = smpsl[i] * lpan + ldl * ffb; rdl = smpsr[i] * rpan + rdl * ffb; //LowPass Filter ldl = ldl * (1.0f - fhidamp) + oldl * fhidamp; rdl = rdl * (1.0f - fhidamp) + oldr * fhidamp; oldl = ldl + DENORMAL_GUARD; oldr = rdl + DENORMAL_GUARD; /* Here do the delay line stuff basically, dl1(dl2(smps)); ^^This runs two flangers in series so you can get a double notch */ ldl = ldelayline0->delay(ldl,dlA, 0, 1, 0); ldl = ldelayline1->delay(ldl,dlB, 0, 1, 0); rdl = rdelayline0->delay(rdl,drA, 0, 1, 0); rdl = rdelayline1->delay(rdl,drB, 0, 1, 0); efxoutl[i] = ldl = ldl * flrcross + rdl * frlcross; efxoutr[i] = rdl = rdl * flrcross + ldl * frlcross; // Increment LFO drA += rx0; drB += rx1; dlA += lx0; dlB += lx1; } } } else { lmodfreq = fdepth + fwidth*(powf(base, lmod) - 1.0f)*ibase; //sets frequency of lowest notch. // 20 <= fdepth <= 4000 // 20 <= width <= 16000 // rmodfreq = fdepth + fwidth*(powf(base, rmod) - 1.0f)*ibase; if (lmodfreq > 10000.0f) lmodfreq = 10000.0f; else if (lmodfreq < 10.0f) lmodfreq = 10.0f; if (rmodfreq > 10000.0) rmodfreq = 10000.0f; else if (rmodfreq < 10.0f) rmodfreq = 10.0f; rflange0 = fSAMPLE_RATE * 0.5f/rmodfreq; //Turn the notch frequency into a number for delay rflange1 = rflange0 * foffset; //Set relationship of second delay line lflange0 = fSAMPLE_RATE * 0.5f/lmodfreq; lflange1 = lflange0 * foffset; //now is a delay expressed in number of samples. Number here //will be fractional, but will use linear interpolation inside the loop to make a decent guess at //the numbers between samples. rx0 = (rflange0 - oldrflange0) * period_const; //amount to add each time around the loop. Less processing of linear LFO interp inside the loop. rx1 = (rflange1 - oldrflange1) * period_const; lx0 = (lflange0 - oldlflange0) * period_const; lx1 = (lflange1 - oldlflange1) * period_const; // Now there is a fractional amount to add drA = oldrflange0; drB = oldrflange1; dlA = oldlflange0; dlB = oldlflange1; // dr, dl variables are the LFO inside the loop. oldrflange0 = rflange0; oldrflange1 = rflange1; oldlflange0 = lflange0; oldlflange1 = lflange1; //lfo ready... for (i = 0; i < PERIOD; i++) { //Delay line utility ldl = ldelay[kl]; rdl = rdelay[kr]; l = ldl * flrcross + rdl * frlcross; r = rdl * flrcross + ldl * frlcross; ldl = l; rdl = r; ldl = smpsl[i] * lpan - ldl * ffb; rdl = smpsr[i] * rpan - rdl * ffb; //LowPass Filter ldelay[kl] = ldl = ldl * (1.0f - fhidamp) + oldl * fhidamp; rdelay[kr] = rdl = rdl * (1.0f - fhidamp) + oldr * fhidamp; oldl = ldl + DENORMAL_GUARD; oldr = rdl + DENORMAL_GUARD; if(Pzero) { //Offset zero reference delay zdl = zldelay[zl]; zdr = zrdelay[zr]; zldelay[zl] = smpsl[i]; zrdelay[zr] = smpsr[i]; if (--zl < 0) //Cycle delay buffer in reverse so delay time can be indexed directly with addition zl = zcenter; if (--zr < 0) zr = zcenter; } //End delay line management, start flanging: //Right Channel, delay A rdif0 = drA - floor(drA); tmp0 = (kr + (int) floor(drA)) % maxx_delay; tmp1 = tmp0 + 1; if (tmp1 >= maxx_delay) tmp1 = 0; //rsA = rdelay[tmp0] + rdif0 * (rdelay[tmp1] - rdelay[tmp0] ); //here is the first right channel delay rsA = rdelay[tmp1] + rdif0 * (rdelay[tmp0] - rsA ); //All-pass interpolator //Right Channel, delay B rdif1 = drB - floor(drB); tmp0 = (kr + (int) floor(drB)) % maxx_delay; tmp1 = tmp0 + 1; if (tmp1 >= maxx_delay) tmp1 = 0; //rsB = rdelay[tmp0] + rdif1 * (rdelay[tmp1] - rdelay[tmp0]); //here is the second right channel delay rsB = rdelay[tmp1] + rdif1 * (rdelay[tmp0] - rsB ); //Left Channel, delay A ldif0 = dlA - floor(dlA); tmp0 = (kl + (int) floor(dlA)) % maxx_delay; tmp1 = tmp0 + 1; if (tmp1 >= maxx_delay) tmp1 = 0; //lsA = ldelay[tmp0] + ldif0 * (ldelay[tmp1] - ldelay[tmp0]); //here is the first left channel delay lsA = ldelay[tmp1] + ldif0 * (ldelay[tmp0] - lsA ); //Left Channel, delay B ldif1 = dlB - floor(dlB); tmp0 = (kl + (int) floor(dlB)) % maxx_delay; tmp1 = tmp0 + 1; if (tmp1 >= maxx_delay) tmp1 = 0; //lsB = ldelay[tmp0] + ldif1 * (ldelay[tmp1] - ldelay[tmp0]); //here is the second left channel delay lsB = ldelay[tmp1] + ldif1 * (ldelay[tmp0] - lsB ); //End flanging, next process outputs if(Pzero) { efxoutl[i]= dry * smpsl[i] + fsubtract * wet * (fsubtract * (lsA + lsB) + zdl); // Make final FX out mix efxoutr[i]= dry * smpsr[i] + fsubtract * wet * (fsubtract * (rsA + rsB) + zdr); } else { efxoutl[i]= dry * smpsl[i] + wet * fsubtract * (lsA + lsB); // Make final FX out mix efxoutr[i]= dry * smpsr[i] + wet * fsubtract * (rsA + rsB); } if (--kl < 0) //Cycle delay buffer in reverse so delay time can be indexed directly with addition kl = maxx_delay; if (--kr < 0) kr = maxx_delay; // Increment LFO drA += rx0; drB += rx1; dlA += lx0; dlB += lx1; }; //end for loop } //end intense if statement };