Skip to content

Commit

Permalink
Add LFO output mode
Browse files Browse the repository at this point in the history
  • Loading branch information
jd-13 committed Jun 21, 2024
1 parent bedd5bf commit 98a1b3b
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
12 changes: 9 additions & 3 deletions WECore/RichterLFO/RichterLFO.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ namespace WECore::Richter {
bool getTempoSyncSwitch() const { return _tempoSyncSwitch; }
bool getInvertSwitch() const { return _invertSwitch; }
int getWave() const { return _wave; }
int getOutputMode() { return _outputMode; }
double getTempoNumer() const { return _tempoNumer; }
double getTempoDenom() const { return _tempoDenom; }
double getFreq() { return _rawFreq; }
Expand All @@ -81,6 +82,7 @@ namespace WECore::Richter {
void setTempoSyncSwitch(bool val) { _tempoSyncSwitch = val; }
void setInvertSwitch(bool val) { _invertSwitch = val; }
inline void setWave(int val);
void setOutputMode(int val) { _outputMode = Parameters::OUTPUTMODE.BoundsCheck(val); }
void setTempoNumer(int val) { _tempoNumer = Parameters::TEMPONUMER.BoundsCheck(val); }
void setTempoDenom (int val) { _tempoDenom = Parameters::TEMPODENOM.BoundsCheck(val); }
void setFreq(double val) { _rawFreq = Parameters::FREQ.BoundsCheck(val); }
Expand Down Expand Up @@ -119,7 +121,8 @@ namespace WECore::Richter {

protected:
int _wave,
_indexOffset;
_indexOffset,
_outputMode;

bool _bypassSwitch,
_tempoSyncSwitch,
Expand Down Expand Up @@ -201,6 +204,7 @@ namespace WECore::Richter {

RichterLFO::RichterLFO() : _wave(Parameters::WAVE.defaultValue),
_indexOffset(0),
_outputMode(Parameters::OUTPUTMODE.defaultValue),
_bypassSwitch(Parameters::LFOSWITCH_DEFAULT),
_tempoSyncSwitch(Parameters::TEMPOSYNC_DEFAULT),
_phaseSyncSwitch(Parameters::PHASESYNC_DEFAULT),
Expand Down Expand Up @@ -394,7 +398,9 @@ namespace WECore::Richter {

const int index {static_cast<int>(_wavetablePosition)};

return _waveArrayPointer[(index + _indexOffset + phaseIndexOffset) % Wavetables::SIZE];
const double wavetableValue {_waveArrayPointer[(index + _indexOffset + phaseIndexOffset) % Wavetables::SIZE]};

return _outputMode == Parameters::OUTPUTMODE.BIPOLAR ? wavetableValue : (wavetableValue + 1);
}

double RichterLFO::_getNextOutputImpl(double /*inSample*/) {
Expand All @@ -412,7 +418,7 @@ namespace WECore::Richter {
_modulatedDepthValue = depth;

if (_bypassSwitch) {
// Produce a value in the range -1:1, invert if needed
// Produce a value in the range -1:1 (or 0:2), invert if needed
return (lfoValue * depth) * (_invertSwitch ? -1 : 1);
} else {
return 0;
Expand Down
10 changes: 10 additions & 0 deletions WECore/RichterLFO/RichterParameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ namespace WECore::Richter::Parameters {

const WaveParameter WAVE;

class OutputModeParameter : public ParameterDefinition::BaseParameter<int> {
public:
OutputModeParameter() : ParameterDefinition::BaseParameter<int>(UNIPOLAR, BIPOLAR, BIPOLAR) {}

static constexpr int UNIPOLAR {1},
BIPOLAR {2};
};

const OutputModeParameter OUTPUTMODE;

const ParameterDefinition::RangedParameter<int> TEMPONUMER(1, 32, 1),
TEMPODENOM(1, 32, 1);

Expand Down
14 changes: 14 additions & 0 deletions WECore/RichterLFO/Tests/RichterLFOPairTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ SCENARIO("RichterLFOPair: Parameters can be set and retrieved correctly") {
CHECK(mLFOPair.LFO.getTempoSyncSwitch() == false);
CHECK(mLFOPair.LFO.getInvertSwitch() == false);
CHECK(mLFOPair.LFO.getWave() == 1);
CHECK(mLFOPair.LFO.getOutputMode() == 2);
CHECK(mLFOPair.LFO.getDepth() == Approx(0.5));
CHECK(mLFOPair.LFO.getFreq() == Approx(2.0));
CHECK(mLFOPair.LFO.getManualPhase() == Approx(0.0));
Expand All @@ -44,6 +45,7 @@ SCENARIO("RichterLFOPair: Parameters can be set and retrieved correctly") {
CHECK(mLFOPair.MOD->getTempoSyncSwitch() == false);
CHECK(mLFOPair.MOD->getInvertSwitch() == false);
CHECK(mLFOPair.MOD->getWave() == 1);
CHECK(mLFOPair.MOD->getOutputMode() == 2);
CHECK(mLFOPair.MOD->getDepth() == Approx(0.5));
CHECK(mLFOPair.MOD->getFreq() == Approx(2.0));
CHECK(mLFOPair.MOD->getManualPhase() == Approx(0.0));
Expand All @@ -58,6 +60,7 @@ SCENARIO("RichterLFOPair: Parameters can be set and retrieved correctly") {
mLFOPair.LFO.setTempoSyncSwitch(true);
mLFOPair.LFO.setInvertSwitch(true);
mLFOPair.LFO.setWave(2);
mLFOPair.LFO.setOutputMode(1);
mLFOPair.LFO.setDepth(0.1);
mLFOPair.LFO.setFreq(3);
mLFOPair.LFO.setManualPhase(0.5);
Expand All @@ -69,6 +72,7 @@ SCENARIO("RichterLFOPair: Parameters can be set and retrieved correctly") {
mLFOPair.MOD->setTempoSyncSwitch(true);
mLFOPair.MOD->setInvertSwitch(true);
mLFOPair.MOD->setWave(3);
mLFOPair.MOD->setOutputMode(1);
mLFOPair.MOD->setDepth(0.5);
mLFOPair.MOD->setFreq(6);
mLFOPair.MOD->setManualPhase(0.7);
Expand All @@ -81,6 +85,7 @@ SCENARIO("RichterLFOPair: Parameters can be set and retrieved correctly") {
CHECK(mLFOPair.LFO.getTempoSyncSwitch() == true);
CHECK(mLFOPair.LFO.getInvertSwitch() == true);
CHECK(mLFOPair.LFO.getWave() == 2);
CHECK(mLFOPair.LFO.getOutputMode() == 1);
CHECK(mLFOPair.LFO.getDepth() == Approx(0.1));
CHECK(mLFOPair.LFO.getFreq() == Approx(3.0));
CHECK(mLFOPair.LFO.getManualPhase() == Approx(0.5));
Expand All @@ -92,6 +97,7 @@ SCENARIO("RichterLFOPair: Parameters can be set and retrieved correctly") {
CHECK(mLFOPair.MOD->getTempoSyncSwitch() == true);
CHECK(mLFOPair.MOD->getInvertSwitch() == true);
CHECK(mLFOPair.MOD->getWave() == 3);
CHECK(mLFOPair.MOD->getOutputMode() == 1);
CHECK(mLFOPair.MOD->getDepth() == Approx(0.5));
CHECK(mLFOPair.MOD->getFreq() == Approx(6.0));
CHECK(mLFOPair.MOD->getManualPhase() == Approx(0.7));
Expand All @@ -108,13 +114,15 @@ SCENARIO("RichterLFOPair: Parameters enforce their bounds correctly") {

WHEN("All parameter values are too low") {
mLFOPair.LFO.setWave(-5);
mLFOPair.LFO.setOutputMode(-5);
mLFOPair.LFO.setDepth(-5);
mLFOPair.LFO.setFreq(-5);
mLFOPair.LFO.setManualPhase(-5);
mLFOPair.LFO.setTempoNumer(-5);
mLFOPair.LFO.setTempoDenom(-5);

mLFOPair.MOD->setWave(-5);
mLFOPair.MOD->setOutputMode(-5);
mLFOPair.MOD->setDepth(-5);
mLFOPair.MOD->setFreq(-5);
mLFOPair.MOD->setManualPhase(-5);
Expand All @@ -123,13 +131,15 @@ SCENARIO("RichterLFOPair: Parameters enforce their bounds correctly") {

THEN("Parameters enforce their lower bounds") {
CHECK(mLFOPair.LFO.getWave() == 1);
CHECK(mLFOPair.LFO.getOutputMode() == 1);
CHECK(mLFOPair.LFO.getDepth() == Approx(0.0));
CHECK(mLFOPair.LFO.getFreq() == Approx(0.0));
CHECK(mLFOPair.LFO.getManualPhase() == Approx(0.0));
CHECK(mLFOPair.LFO.getTempoNumer() == Approx(1.0));
CHECK(mLFOPair.LFO.getTempoDenom() == Approx(1.0));

CHECK(mLFOPair.MOD->getWave() == 1);
CHECK(mLFOPair.MOD->getOutputMode() == 1);
CHECK(mLFOPair.MOD->getDepth() == Approx(0.0));
CHECK(mLFOPair.MOD->getFreq() == Approx(0.0));
CHECK(mLFOPair.MOD->getManualPhase() == Approx(0.0));
Expand All @@ -140,13 +150,15 @@ SCENARIO("RichterLFOPair: Parameters enforce their bounds correctly") {

WHEN("All parameter values are too high") {
mLFOPair.LFO.setWave(100);
mLFOPair.LFO.setOutputMode(100);
mLFOPair.LFO.setDepth(100);
mLFOPair.LFO.setFreq(100);
mLFOPair.LFO.setManualPhase(10000);
mLFOPair.LFO.setTempoNumer(100);
mLFOPair.LFO.setTempoDenom(100);

mLFOPair.MOD->setWave(100);
mLFOPair.MOD->setOutputMode(100);
mLFOPair.MOD->setDepth(100);
mLFOPair.MOD->setFreq(100);
mLFOPair.MOD->setManualPhase(10000);
Expand All @@ -155,13 +167,15 @@ SCENARIO("RichterLFOPair: Parameters enforce their bounds correctly") {

THEN("Parameters enforce their upper bounds") {
CHECK(mLFOPair.LFO.getWave() == 4);
CHECK(mLFOPair.LFO.getOutputMode() == 2);
CHECK(mLFOPair.LFO.getDepth() == Approx(1.0));
CHECK(mLFOPair.LFO.getFreq() == Approx(20.0));
CHECK(mLFOPair.LFO.getManualPhase() == Approx(360.0));
CHECK(mLFOPair.LFO.getTempoNumer() == Approx(32.0));
CHECK(mLFOPair.LFO.getTempoDenom() == Approx(32.0));

CHECK(mLFOPair.MOD->getWave() == 4);
CHECK(mLFOPair.MOD->getOutputMode() == 2);
CHECK(mLFOPair.MOD->getDepth() == Approx(1.0));
CHECK(mLFOPair.MOD->getFreq() == Approx(20.0));
CHECK(mLFOPair.MOD->getManualPhase() == Approx(360.0));
Expand Down

0 comments on commit 98a1b3b

Please sign in to comment.