mirror of
https://github.com/thestk/stk
synced 2026-01-15 14:01:52 +00:00
Version 4.0
This commit is contained in:
committed by
Stephen Sinclair
parent
3f126af4e5
commit
81475b04c5
142
src/PRCRev.cpp
142
src/PRCRev.cpp
@@ -1,113 +1,93 @@
|
||||
/*******************************************/
|
||||
/* 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. */
|
||||
/*******************************************/
|
||||
/***************************************************/
|
||||
/*! \class PRCRev
|
||||
\brief Perry's simple reverberator class.
|
||||
|
||||
This class is based on some of the famous
|
||||
Stanford/CCRMA reverbs (NRev, KipRev), which
|
||||
were based on the Chowning/Moorer/Schroeder
|
||||
reverberators using networks of simple allpass
|
||||
and comb delay filters. This class implements
|
||||
two series allpass units and two parallel comb
|
||||
filters.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "PRCRev.h"
|
||||
#include <math.h>
|
||||
|
||||
PRCRev :: PRCRev(MY_FLOAT T60)
|
||||
{
|
||||
int lens[4]={353,1097,1777,2137};
|
||||
double srscale = SRATE / 44100.0;
|
||||
int val, i;
|
||||
// Delay lengths for 44100 Hz sample rate.
|
||||
int lengths[4]= {353, 1097, 1777, 2137};
|
||||
double scaler = Stk::sampleRate() / 44100.0;
|
||||
|
||||
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;
|
||||
}
|
||||
// Scale the delay lengths if necessary.
|
||||
int delay, i;
|
||||
if ( scaler != 1.0 ) {
|
||||
for (i=0; i<4; i++) {
|
||||
delay = (int) floor(scaler * lengths[i]);
|
||||
if ( (delay & 1) == 0) delay++;
|
||||
while ( !this->isPrime(delay) ) delay += 2;
|
||||
lengths[i] = delay;
|
||||
}
|
||||
}
|
||||
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)));
|
||||
|
||||
for (i=0; i<2; i++) {
|
||||
allpassDelays[i] = new Delay( lengths[i], lengths[i] );
|
||||
combDelays[i] = new Delay( lengths[i+2], lengths[i+2] );
|
||||
combCoefficient[i] = pow(10,(-3 * lengths[i+2] / (T60 * Stk::sampleRate())));
|
||||
}
|
||||
|
||||
allPassCoeff = (MY_FLOAT) 0.7;
|
||||
effectMix = (MY_FLOAT) 0.5;
|
||||
allpassCoefficient = 0.7;
|
||||
effectMix = 0.5;
|
||||
this->clear();
|
||||
}
|
||||
|
||||
PRCRev :: ~PRCRev()
|
||||
{
|
||||
delete APdelayLine[0];
|
||||
delete APdelayLine[1];
|
||||
delete CdelayLine[0];
|
||||
delete CdelayLine[1];
|
||||
delete allpassDelays[0];
|
||||
delete allpassDelays[1];
|
||||
delete combDelays[0];
|
||||
delete combDelays[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;
|
||||
allpassDelays[0]->clear();
|
||||
allpassDelays[1]->clear();
|
||||
combDelays[0]->clear();
|
||||
combDelays[1]->clear();
|
||||
lastOutput[0] = 0.0;
|
||||
lastOutput[1] = 0.0;
|
||||
}
|
||||
|
||||
MY_FLOAT PRCRev :: tick(MY_FLOAT input)
|
||||
{
|
||||
MY_FLOAT temp,temp0,temp1,temp2,temp3;
|
||||
MY_FLOAT temp, temp0, temp1, temp2, temp3;
|
||||
|
||||
temp = APdelayLine[0]->lastOut();
|
||||
temp0 = allPassCoeff * temp;
|
||||
temp = allpassDelays[0]->lastOut();
|
||||
temp0 = allpassCoefficient * temp;
|
||||
temp0 += input;
|
||||
APdelayLine[0]->tick(temp0);
|
||||
temp0 = -(allPassCoeff * temp0) + temp;
|
||||
allpassDelays[0]->tick(temp0);
|
||||
temp0 = -(allpassCoefficient * temp0) + temp;
|
||||
|
||||
temp = APdelayLine[1]->lastOut();
|
||||
temp1 = allPassCoeff * temp;
|
||||
temp = allpassDelays[1]->lastOut();
|
||||
temp1 = allpassCoefficient * temp;
|
||||
temp1 += temp0;
|
||||
APdelayLine[1]->tick(temp1);
|
||||
temp1 = -(allPassCoeff * temp1) + temp;
|
||||
allpassDelays[1]->tick(temp1);
|
||||
temp1 = -(allpassCoefficient * temp1) + temp;
|
||||
|
||||
temp2 = temp1 + (combCoeff[0] * CdelayLine[0]->lastOut());
|
||||
temp3 = temp1 + (combCoeff[1] * CdelayLine[1]->lastOut());
|
||||
temp2 = temp1 + (combCoefficient[0] * combDelays[0]->lastOut());
|
||||
temp3 = temp1 + (combCoefficient[1] * combDelays[1]->lastOut());
|
||||
|
||||
lastOutL = effectMix * (CdelayLine[0]->tick(temp2));
|
||||
lastOutR = effectMix * (CdelayLine[1]->tick(temp3));
|
||||
lastOutput[0] = effectMix * (combDelays[0]->tick(temp2));
|
||||
lastOutput[1] = effectMix * (combDelays[1]->tick(temp3));
|
||||
temp = (MY_FLOAT) (1.0 - effectMix) * input;
|
||||
lastOutL += temp;
|
||||
lastOutR += temp;
|
||||
lastOutput[0] += temp;
|
||||
lastOutput[1] += temp;
|
||||
|
||||
return (lastOutL + lastOutR) * (MY_FLOAT) 0.5;
|
||||
return (lastOutput[0] + lastOutput[1]) * (MY_FLOAT) 0.5;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user