#include "LFO.h"
|
|
|
LFO::LFO()
|
{
|
|
}
|
|
LFO::LFO(int waveformType)
|
{
|
setWaveformType(waveformType);
|
}
|
|
void LFO::prepare(double sampleRate)
|
{
|
setSampleRate(sampleRate);
|
modCounter = 0.0;
|
modCounter90 = 0.25;
|
setFrequency(frequency);
|
}
|
|
double LFO::getNextOutputSample(int phaseType)
|
{
|
generateNextOutputSample();
|
|
switch(phaseType)
|
{
|
case LFOPhase::Normal:
|
return outNormal;
|
break;
|
case LFOPhase::Inverted:
|
return outInverted;
|
break;
|
case LFOPhase::QuadPhase:
|
return outQuadPhase;
|
break;
|
case LFOPhase::QuadPhaseInverted:
|
return outQuadPhaseInverted;
|
break;
|
default:
|
return outNormal;
|
break;
|
}
|
}
|
|
void LFO::setWaveformType(int waveformType)
|
{
|
switch(waveformType)
|
{
|
case Waveforms::Triangle:
|
waveformType = Waveforms::Triangle;
|
break;
|
case Waveforms::Sine:
|
waveformType = Waveforms::Sine;
|
break;
|
case Waveforms::Saw:
|
waveformType = Waveforms::Saw;
|
break;
|
}
|
}
|
|
int LFO::getWaveformType()
|
{
|
return waveformType;
|
}
|
|
void LFO::setFrequency(double freq)
|
{
|
frequency = freq;
|
phaseInc = frequency / sampleRate;
|
}
|
|
double LFO::getFrequency()
|
{
|
return frequency;
|
}
|
|
void LFO::setSampleRate(double sampleRate)
|
{
|
this->sampleRate = sampleRate;
|
}
|
|
double LFO::getSampleRate()
|
{
|
return sampleRate;
|
}
|
|
double LFO::unipolarToBipolar(double value)
|
{
|
return 2.0*value - 1.0;
|
}
|
|
void LFO::generateNextOutputSample()
|
{
|
moduloWrap(modCounter, phaseInc);
|
|
modCounter90 = modCounter;
|
|
moduloAdvanceAndWrap(modCounter90, 0.25);
|
|
outNormal = 0.0;
|
outInverted = 0.0;
|
outQuadPhase = 0.0;
|
outQuadPhaseInverted = 0.0;
|
|
switch(waveformType)
|
{
|
case Waveforms::Triangle:
|
// Normal Output
|
outNormal = unipolarToBipolar(modCounter);
|
outNormal = 2.0*fabs(outNormal) - 1.0;
|
|
// 90 Degree phase shift
|
outQuadPhase = unipolarToBipolar(modCounter90);
|
outQuadPhase = 2.0*fabs(outQuadPhase) - 1.0;
|
|
break;
|
|
case Waveforms::Sine:
|
double angle;
|
|
// Angle Calculation
|
angle = modCounter*2.0*PI - PI;
|
|
// Normal Output
|
outNormal = parabolicSine(-angle);
|
|
// 90 Degree shift angle calculation
|
angle = modCounter90*2.0*PI - PI;
|
|
// 90 Degree phase shift
|
outQuadPhase = parabolicSine(-angle);
|
|
break;
|
|
case Waveforms::Saw:
|
// Normal Output
|
outNormal = unipolarToBipolar(modCounter);
|
|
// 90 Degree Shift
|
outQuadPhase = unipolarToBipolar(modCounter90);
|
|
break;
|
|
}
|
|
// Inverted Outputs
|
|
// Inverted Normal Output
|
outInverted = -outNormal;
|
|
// Inverted 90 Degree
|
outQuadPhaseInverted = -outQuadPhase;
|
|
moduloAdvance(modCounter, phaseInc);
|
}
|
|
void LFO::moduloAdvance(double& modCounter, double phaseInc)
|
{
|
modCounter += phaseInc;
|
}
|
|
void LFO::moduloWrap(double& modCounter, double phaseInc)
|
{
|
// Positive Frequencies
|
if(phaseInc > 0 && modCounter >= 1.0)
|
modCounter -= 1.0;
|
|
// Negative Frequencies
|
if(phaseInc < 0 && modCounter <= 0.0)
|
modCounter += 1.0;
|
}
|
|
void LFO::moduloAdvanceAndWrap(double& modCounter, double phaseInc)
|
{
|
// Advance
|
modCounter += phaseInc;
|
|
// Check if Wrap is needed
|
|
// Positive Frequencies
|
if(phaseInc > 0 && modCounter >= 1.0)
|
modCounter -= 1.0;
|
|
// Negative Frequencies
|
if(phaseInc < 0 && modCounter <= 0.0)
|
modCounter += 1.0;
|
}
|
|
double LFO::parabolicSine(double angle)
|
{
|
const double B = 4.0 / PI;
|
const double C = -4.0 / (PI* PI);
|
const double P = 0.225;
|
|
double y = B * angle + C * angle * fabs(angle);
|
|
return (P * (y * fabs(y) - y) + y);
|
}
|