mirror of
https://github.com/thestk/stk
synced 2026-01-11 20:11:52 +00:00
114 lines
2.7 KiB
C++
114 lines
2.7 KiB
C++
/*******************************************/
|
|
/* PRCRev, a simple reverb unit */
|
|
/* by Perry Cook, 1996. */
|
|
/* Incorporated into the Reverb superclass */
|
|
/* by Gary Scavone, 1998. */
|
|
/* */
|
|
/* This is based on some of the famous */
|
|
/* Stanford CCRMA reverbs (NRev, KipRev) */
|
|
/* all based on the the Chowning/Moorer/ */
|
|
/* Schroeder reverberators, which use */
|
|
/* networks of simple allpass and comb */
|
|
/* delay filters. This particular */
|
|
/* structure consists of 2 allpass units */
|
|
/* in series followed by 2 comb filters in */
|
|
/* parallel. */
|
|
/*******************************************/
|
|
|
|
#include "PRCRev.h"
|
|
|
|
PRCRev :: PRCRev(MY_FLOAT T60)
|
|
{
|
|
int lens[4]={353,1097,1777,2137};
|
|
double srscale = SRATE / 44100.0;
|
|
int val, i;
|
|
|
|
if (SRATE < 44100.0) {
|
|
for (i=0; i<4; i++) {
|
|
val = (int) floor(srscale * lens[i]);
|
|
if ((val & 1) == 0) val++;
|
|
while (!this->isprime(val)) val += 2;
|
|
lens[i] = val;
|
|
}
|
|
}
|
|
for (i=0; i<2; i++)
|
|
{
|
|
APdelayLine[i] = new DLineN(lens[i] + 2);
|
|
APdelayLine[i]->setDelay(lens[i]);
|
|
CdelayLine[i] = new DLineN(lens[i+2] + 2);
|
|
CdelayLine[i]->setDelay(lens[i+2]);
|
|
combCoeff[i] = pow(10,(-3 * lens[i+2] / (T60 * SRATE)));
|
|
}
|
|
|
|
allPassCoeff = (MY_FLOAT) 0.7;
|
|
effectMix = (MY_FLOAT) 0.5;
|
|
this->clear();
|
|
}
|
|
|
|
PRCRev :: ~PRCRev()
|
|
{
|
|
delete APdelayLine[0];
|
|
delete APdelayLine[1];
|
|
delete CdelayLine[0];
|
|
delete CdelayLine[1];
|
|
}
|
|
|
|
void PRCRev :: clear()
|
|
{
|
|
APdelayLine[0]->clear();
|
|
APdelayLine[1]->clear();
|
|
CdelayLine[0]->clear();
|
|
CdelayLine[1]->clear();
|
|
lastOutL = (MY_FLOAT) 0.0;
|
|
lastOutR = (MY_FLOAT) 0.0;
|
|
}
|
|
|
|
void PRCRev :: setEffectMix(MY_FLOAT mix)
|
|
{
|
|
effectMix = mix;
|
|
}
|
|
|
|
MY_FLOAT PRCRev :: lastOutput()
|
|
{
|
|
return (lastOutL + lastOutR) * (MY_FLOAT) 0.5;
|
|
}
|
|
|
|
MY_FLOAT PRCRev :: lastOutputL()
|
|
{
|
|
return lastOutL;
|
|
}
|
|
|
|
MY_FLOAT PRCRev :: lastOutputR()
|
|
{
|
|
return lastOutR;
|
|
}
|
|
|
|
MY_FLOAT PRCRev :: tick(MY_FLOAT input)
|
|
{
|
|
MY_FLOAT temp,temp0,temp1,temp2,temp3;
|
|
|
|
temp = APdelayLine[0]->lastOut();
|
|
temp0 = allPassCoeff * temp;
|
|
temp0 += input;
|
|
APdelayLine[0]->tick(temp0);
|
|
temp0 = -(allPassCoeff * temp0) + temp;
|
|
|
|
temp = APdelayLine[1]->lastOut();
|
|
temp1 = allPassCoeff * temp;
|
|
temp1 += temp0;
|
|
APdelayLine[1]->tick(temp1);
|
|
temp1 = -(allPassCoeff * temp1) + temp;
|
|
|
|
temp2 = temp1 + (combCoeff[0] * CdelayLine[0]->lastOut());
|
|
temp3 = temp1 + (combCoeff[1] * CdelayLine[1]->lastOut());
|
|
|
|
lastOutL = effectMix * (CdelayLine[0]->tick(temp2));
|
|
lastOutR = effectMix * (CdelayLine[1]->tick(temp3));
|
|
temp = (MY_FLOAT) (1.0 - effectMix) * input;
|
|
lastOutL += temp;
|
|
lastOutR += temp;
|
|
|
|
return (lastOutL + lastOutR) * (MY_FLOAT) 0.5;
|
|
|
|
}
|