Version 4.4.0

This commit is contained in:
Gary Scavone
2013-09-29 23:11:39 +02:00
committed by Stephen Sinclair
parent d199342e86
commit eccd8c9981
287 changed files with 11712 additions and 7676 deletions

View File

@@ -2,38 +2,41 @@
/*! \class JCRev
\brief John Chowning's reverberator class.
This class is derived from the CLM JCRev
function, which is based on the use of
networks of simple allpass and comb delay
filters. This class implements three series
allpass units, followed by four parallel comb
filters, and two decorrelation delay lines in
parallel at the output.
This class takes a monophonic input signal and produces a stereo
output signal. It is derived from the CLM JCRev function, which
is based on the use of networks of simple allpass and comb delay
filters. This class implements three series allpass units,
followed by four parallel comb filters, and two decorrelation
delay lines in parallel at the output.
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
*/
/***************************************************/
#include "JCRev.h"
#include <math.h>
#include <cmath>
JCRev :: JCRev(StkFloat T60)
namespace stk {
JCRev :: JCRev( StkFloat T60 )
{
lastFrame_.resize( 1, 2, 0.0 ); // resize lastFrame_ for stereo output
// Delay lengths for 44100 Hz sample rate.
int lengths[9] = {1777, 1847, 1993, 2137, 389, 127, 43, 211, 179};
double scaler = Stk::sampleRate() / 44100.0;
int delay, i;
if ( scaler != 1.0 ) {
for (i=0; i<9; i++) {
delay = (int) floor(scaler * lengths[i]);
for ( i=0; i<9; 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<3; i++) {
for ( i=0; i<3; i++ ) {
allpassDelays_[i].setMaximumDelay( lengths[i+4] );
allpassDelays_[i].setDelay( lengths[i+4] );
}
@@ -53,10 +56,6 @@ JCRev :: JCRev(StkFloat T60)
this->clear();
}
JCRev :: ~JCRev()
{
}
void JCRev :: clear()
{
allpassDelays_[0].clear();
@@ -68,8 +67,8 @@ void JCRev :: clear()
combDelays_[3].clear();
outRightDelay_.clear();
outLeftDelay_.clear();
lastOutput_[0] = 0.0;
lastOutput_[1] = 0.0;
lastFrame_[0] = 0.0;
lastFrame_[1] = 0.0;
}
void JCRev :: setT60( StkFloat T60 )
@@ -78,46 +77,44 @@ void JCRev :: setT60( StkFloat T60 )
combCoefficient_[i] = pow(10.0, (-3.0 * combDelays_[i].getDelay() / (T60 * Stk::sampleRate())));
}
StkFloat JCRev :: computeSample(StkFloat input)
StkFrames& JCRev :: tick( StkFrames& frames, unsigned int channel )
{
StkFloat temp, temp0, temp1, temp2, temp3, temp4, temp5, temp6;
StkFloat filtout;
#if defined(_STK_DEBUG_)
if ( channel >= frames.channels() - 1 ) {
errorString_ << "JCRev::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
temp = allpassDelays_[0].lastOut();
temp0 = allpassCoefficient_ * temp;
temp0 += input;
allpassDelays_[0].tick(temp0);
temp0 = -(allpassCoefficient_ * temp0) + temp;
temp = allpassDelays_[1].lastOut();
temp1 = allpassCoefficient_ * temp;
temp1 += temp0;
allpassDelays_[1].tick(temp1);
temp1 = -(allpassCoefficient_ * temp1) + temp;
temp = allpassDelays_[2].lastOut();
temp2 = allpassCoefficient_ * temp;
temp2 += temp1;
allpassDelays_[2].tick(temp2);
temp2 = -(allpassCoefficient_ * temp2) + temp;
temp3 = temp2 + (combCoefficient_[0] * combDelays_[0].lastOut());
temp4 = temp2 + (combCoefficient_[1] * combDelays_[1].lastOut());
temp5 = temp2 + (combCoefficient_[2] * combDelays_[2].lastOut());
temp6 = temp2 + (combCoefficient_[3] * combDelays_[3].lastOut());
StkFloat *samples = &frames[channel];
unsigned int hop = frames.channels();
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples = tick( *samples );
*samples++;
*samples = lastFrame_[1];
}
combDelays_[0].tick(temp3);
combDelays_[1].tick(temp4);
combDelays_[2].tick(temp5);
combDelays_[3].tick(temp6);
filtout = temp3 + temp4 + temp5 + temp6;
lastOutput_[0] = effectMix_ * (outLeftDelay_.tick(filtout));
lastOutput_[1] = effectMix_ * (outRightDelay_.tick(filtout));
temp = (1.0 - effectMix_) * input;
lastOutput_[0] += temp;
lastOutput_[1] += temp;
return Effect::lastOut();
return frames;
}
StkFrames& JCRev :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() - 1 ) {
errorString_ << "JCRev::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *iSamples = &iFrames[iChannel];
StkFloat *oSamples = &oFrames[oChannel];
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
*oSamples++ = tick( *iSamples );
*oSamples = lastFrame_[1];
}
return iFrames;
}
} // stk namespace