BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

commit 3a0fa09839b4085258974a39eb1fde240cd845a8
parent 745a7b48c9b4066574684472635cf9b7a3d386bf
Author: Matt Demanett <matt@demanett.net>
Date:   Wed, 25 Sep 2019 22:54:31 -0400

Poly: cleanup.

Diffstat:
Msrc/AD.cpp | 42+++++++++++++++++++++---------------------
Msrc/ADSR.cpp | 36++++++++++++++++++------------------
Msrc/CVD.cpp | 56+++++++++++++++++++++++++++-----------------------------
Msrc/CVD.hpp | 7-------
Msrc/DADSRH.cpp | 24++++++++++--------------
Msrc/DADSRHPlus.cpp | 24++++++++++--------------
Msrc/DGate.cpp | 52+++++++++++++++++++++++++---------------------------
Msrc/EightFO.cpp | 86++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Follow.cpp | 6++----
Msrc/LFO.cpp | 60++++++++++++++++++++++++++++++------------------------------
Msrc/Lmtr.cpp | 46++++++++++++++++++++++++----------------------
Msrc/Nsgt.cpp | 48+++++++++++++++++++++++++-----------------------
Msrc/Pressor.cpp | 68+++++++++++++++++++++++++++++++++++---------------------------------
Msrc/Shaper.cpp | 22+++++++++-------------
Msrc/ShaperPlus.cpp | 22+++++++++-------------
Msrc/VCO.cpp | 64++++++++++++++++++++++++++++++++--------------------------------
Msrc/XCO.cpp | 130++++++++++++++++++++++++++++++++++++++++----------------------------------------
17 files changed, 385 insertions(+), 408 deletions(-)

diff --git a/src/AD.cpp b/src/AD.cpp @@ -17,17 +17,13 @@ void AD::Engine::sampleRateChange() { void AD::reset() { for (int c = 0; c < _channels; ++c) { - if (_engines[c]) { - _engines[c]->reset(); - } + _engines[c]->reset(); } } void AD::sampleRateChange() { for (int c = 0; c < _channels; ++c) { - if (_engines[c]) { - _engines[c]->sampleRateChange(); - } + _engines[c]->sampleRateChange(); } } @@ -51,19 +47,21 @@ void AD::removeEngine(int c) { } void AD::modulateChannel(int c) { + Engine& e = *_engines[c]; + float attack = powf(params[ATTACK_PARAM].getValue(), 2.0f); if (inputs[ATTACK_INPUT].isConnected()) { attack *= clamp(inputs[ATTACK_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } - _engines[c]->envelope.setAttack(_engines[c]->attackSL.next(attack * 10.f)); + e.envelope.setAttack(e.attackSL.next(attack * 10.f)); float decay = powf(params[DECAY_PARAM].getValue(), 2.0f); if (inputs[DECAY_INPUT].isConnected()) { decay *= clamp(inputs[DECAY_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } - _engines[c]->envelope.setDecay(_engines[c]->decaySL.next(decay * 10.f)); + e.envelope.setDecay(e.decaySL.next(decay * 10.f)); - _engines[c]->envelope.setLinearShape(_linearMode); + e.envelope.setLinearShape(_linearMode); } void AD::always(const ProcessArgs& args) { @@ -73,23 +71,25 @@ void AD::always(const ProcessArgs& args) { } void AD::processChannel(const ProcessArgs& args, int c) { - _engines[c]->trigger.process(inputs[TRIGGER_INPUT].getVoltage(c)); - if (!_engines[c]->on && (_engines[c]->trigger.isHigh() || (_loopMode && _engines[c]->envelope.isStage(ADSR::STOPPED_STAGE)))) { - _engines[c]->on = true; + Engine& e = *_engines[c]; + + e.trigger.process(inputs[TRIGGER_INPUT].getVoltage(c)); + if (!e.on && (e.trigger.isHigh() || (_loopMode && e.envelope.isStage(ADSR::STOPPED_STAGE)))) { + e.on = true; } - _engines[c]->envelope.setGate(_engines[c]->on); + e.envelope.setGate(e.on); outputs[ENV_OUTPUT].setChannels(_channels); - outputs[ENV_OUTPUT].setVoltage(_engines[c]->envelope.next() * 10.0f, c); - if (_engines[c]->on && _engines[c]->envelope.isStage(ADSR::SUSTAIN_STAGE)) { - _engines[c]->envelope.reset(); - _engines[c]->on = false; - _engines[c]->eocPulseGen.trigger(0.001f); + outputs[ENV_OUTPUT].setVoltage(e.envelope.next() * 10.0f, c); + if (e.on && e.envelope.isStage(ADSR::SUSTAIN_STAGE)) { + e.envelope.reset(); + e.on = false; + e.eocPulseGen.trigger(0.001f); } outputs[EOC_OUTPUT].setChannels(_channels); - outputs[EOC_OUTPUT].setVoltage(_engines[c]->eocPulseGen.process(APP->engine->getSampleTime()) ? 5.0f : 0.0f, c); + outputs[EOC_OUTPUT].setVoltage(e.eocPulseGen.process(APP->engine->getSampleTime()) ? 5.0f : 0.0f, c); - _attackLightSum += _engines[c]->envelope.isStage(ADSR::ATTACK_STAGE); - _decayLightSum += _engines[c]->envelope.isStage(ADSR::DECAY_STAGE); + _attackLightSum += e.envelope.isStage(ADSR::ATTACK_STAGE); + _decayLightSum += e.envelope.isStage(ADSR::DECAY_STAGE); } void AD::postProcess(const ProcessArgs& args) { diff --git a/src/ADSR.cpp b/src/ADSR.cpp @@ -12,17 +12,13 @@ void ADSR::Engine::sampleRateChange() { void ADSR::reset() { for (int c = 0; c < _channels; ++c) { - if (_engines[c]) { - _engines[c]->reset(); - } + _engines[c]->reset(); } } void ADSR::sampleRateChange() { for (int c = 0; c < _channels; ++c) { - if (_engines[c]) { - _engines[c]->sampleRateChange(); - } + _engines[c]->sampleRateChange(); } } @@ -46,11 +42,13 @@ void ADSR::removeEngine(int c) { } void ADSR::modulateChannel(int c) { - _engines[c]->envelope.setAttack(powf(params[ATTACK_PARAM].getValue(), 2.0f) * 10.f); - _engines[c]->envelope.setDecay(powf(params[DECAY_PARAM].getValue(), 2.0f) * 10.f); - _engines[c]->envelope.setSustain(params[SUSTAIN_PARAM].getValue()); - _engines[c]->envelope.setRelease(powf(params[RELEASE_PARAM].getValue(), 2.0f) * 10.f); - _engines[c]->envelope.setLinearShape(_linearMode); + Engine& e = *_engines[c]; + + e.envelope.setAttack(powf(params[ATTACK_PARAM].getValue(), 2.0f) * 10.f); + e.envelope.setDecay(powf(params[DECAY_PARAM].getValue(), 2.0f) * 10.f); + e.envelope.setSustain(params[SUSTAIN_PARAM].getValue()); + e.envelope.setRelease(powf(params[RELEASE_PARAM].getValue(), 2.0f) * 10.f); + e.envelope.setLinearShape(_linearMode); } void ADSR::always(const ProcessArgs& args) { @@ -59,15 +57,17 @@ void ADSR::always(const ProcessArgs& args) { } void ADSR::processChannel(const ProcessArgs& args, int c) { - _engines[c]->gateTrigger.process(inputs[GATE_INPUT].getVoltage(c)); - _engines[c]->envelope.setGate(_engines[c]->gateTrigger.isHigh()); + Engine& e = *_engines[c]; + + e.gateTrigger.process(inputs[GATE_INPUT].getVoltage(c)); + e.envelope.setGate(e.gateTrigger.isHigh()); outputs[OUT_OUTPUT].setChannels(_channels); - outputs[OUT_OUTPUT].setVoltage(_engines[c]->envelope.next() * 10.0f, c); + outputs[OUT_OUTPUT].setVoltage(e.envelope.next() * 10.0f, c); - _attackLightSum += _engines[c]->envelope.isStage(dsp::ADSR::ATTACK_STAGE); - _decayLightSum += _engines[c]->envelope.isStage(dsp::ADSR::DECAY_STAGE); - _sustainLightSum += _engines[c]->envelope.isStage(dsp::ADSR::SUSTAIN_STAGE); - _releaseLightSum += _engines[c]->envelope.isStage(dsp::ADSR::RELEASE_STAGE); + _attackLightSum += e.envelope.isStage(dsp::ADSR::ATTACK_STAGE); + _decayLightSum += e.envelope.isStage(dsp::ADSR::DECAY_STAGE); + _sustainLightSum += e.envelope.isStage(dsp::ADSR::SUSTAIN_STAGE); + _releaseLightSum += e.envelope.isStage(dsp::ADSR::RELEASE_STAGE); } void ADSR::postProcess(const ProcessArgs& args) { diff --git a/src/CVD.cpp b/src/CVD.cpp @@ -2,10 +2,8 @@ #include "CVD.hpp" void CVD::sampleRateChange() { - for (int i = 0; i < _channels; ++i) { - if (_engines[i]) { - _engines[i]->delay.setSampleRate(APP->engine->getSampleRate()); - } + for (int c = 0; c < _channels; ++c) { + _engines[c]->delay.setSampleRate(APP->engine->getSampleRate()); } } @@ -23,38 +21,38 @@ void CVD::removeEngine(int c) { } void CVD::modulateChannel(int c) { - if (_engines[c]) { - float time = params[TIME_PARAM].getValue(); - if (inputs[TIME_INPUT].isConnected()) { - time *= clamp(inputs[TIME_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); + Engine& e = *_engines[c]; + + float time = params[TIME_PARAM].getValue(); + if (inputs[TIME_INPUT].isConnected()) { + time *= clamp(inputs[TIME_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); + } + switch ((int)roundf(params[TIME_SCALE_PARAM].getValue())) { + case 0: { + time /= 100.f; + break; } - switch ((int)roundf(params[TIME_SCALE_PARAM].getValue())) { - case 0: { - time /= 100.f; - break; - } - case 1: { - time /= 10.f; - break; - } + case 1: { + time /= 10.f; + break; } - _engines[c]->delay.setTime(time); + } + e.delay.setTime(time); - float mix = params[MIX_PARAM].getValue(); - if (inputs[MIX_INPUT].isConnected()) { - mix = clamp(mix + inputs[MIX_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); - } - _engines[c]->mix.setParams(mix); + float mix = params[MIX_PARAM].getValue(); + if (inputs[MIX_INPUT].isConnected()) { + mix = clamp(mix + inputs[MIX_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); } + e.mix.setParams(mix); } void CVD::processChannel(const ProcessArgs& args, int c) { - if (_engines[c]) { - float in = inputs[IN_INPUT].getPolyVoltage(c); - float delayed = _engines[c]->delay.next(in); - outputs[OUT_OUTPUT].setChannels(_channels); - outputs[OUT_OUTPUT].setVoltage(_engines[c]->mix.next(in, delayed), c); - } + Engine& e = *_engines[c]; + + float in = inputs[IN_INPUT].getPolyVoltage(c); + float delayed = e.delay.next(in); + outputs[OUT_OUTPUT].setChannels(_channels); + outputs[OUT_OUTPUT].setVoltage(e.mix.next(in, delayed), c); } struct CVDWidget : ModuleWidget { diff --git a/src/CVD.hpp b/src/CVD.hpp @@ -49,13 +49,6 @@ struct CVD : BGModule { sampleRateChange(); } - virtual ~CVD() { - for (int i = 0; i < maxChannels; ++i) { - if (_engines[i]) { - delete _engines[i]; - } - } - } void sampleRateChange() override; int channels() override; diff --git a/src/DADSRH.cpp b/src/DADSRH.cpp @@ -2,10 +2,8 @@ #include "DADSRH.hpp" void DADSRH::reset() { - for (int c = 0; c < maxChannels; ++c) { - if (_core[c]) { - _core[c]->reset(); - } + for (int c = 0; c < _channels; ++c) { + _core[c]->reset(); } } @@ -82,14 +80,12 @@ void DADSRH::postProcess(const ProcessArgs& args) { float decaySum = 0.0f; float sustainSum = 0.0f; float releaseSum = 0.0f; - for (int c = 0; c < maxChannels; ++c) { - if (_core[c]) { - delaySum += _delayLights[c]; - attackSum += _attackLights[c]; - decaySum += _decayLights[c]; - sustainSum += _sustainLights[c]; - releaseSum += _releaseLights[c]; - } + for (int c = 0; c < _channels; ++c) { + delaySum += _delayLights[c]; + attackSum += _attackLights[c]; + decaySum += _decayLights[c]; + sustainSum += _sustainLights[c]; + releaseSum += _releaseLights[c]; } lights[DELAY_LIGHT].value = delaySum / (float)_channels; lights[ATTACK_LIGHT].value = attackSum / (float)_channels; @@ -99,8 +95,8 @@ void DADSRH::postProcess(const ProcessArgs& args) { } bool DADSRH::shouldTriggerOnNextLoad() { - for (int c = 0; c < maxChannels; ++c) { - if (_core[c] && _core[c]->_stage != _core[c]->STOPPED_STAGE) { + for (int c = 0; c < _channels; ++c) { + if (_core[c]->_stage != _core[c]->STOPPED_STAGE) { return true; } } diff --git a/src/DADSRHPlus.cpp b/src/DADSRHPlus.cpp @@ -2,10 +2,8 @@ #include "DADSRHPlus.hpp" void DADSRHPlus::reset() { - for (int c = 0; c < maxChannels; ++c) { - if (_core[c]) { - _core[c]->reset(); - } + for (int c = 0; c < _channels; ++c) { + _core[c]->reset(); } } @@ -82,14 +80,12 @@ void DADSRHPlus::postProcess(const ProcessArgs& args) { float decaySum = 0.0f; float sustainSum = 0.0f; float releaseSum = 0.0f; - for (int c = 0; c < maxChannels; ++c) { - if (_core[c]) { - delaySum += _delayLights[c]; - attackSum += _attackLights[c]; - decaySum += _decayLights[c]; - sustainSum += _sustainLights[c]; - releaseSum += _releaseLights[c]; - } + for (int c = 0; c < _channels; ++c) { + delaySum += _delayLights[c]; + attackSum += _attackLights[c]; + decaySum += _decayLights[c]; + sustainSum += _sustainLights[c]; + releaseSum += _releaseLights[c]; } lights[DELAY_LIGHT].value = delaySum / (float)_channels; lights[ATTACK_LIGHT].value = attackSum / (float)_channels; @@ -99,8 +95,8 @@ void DADSRHPlus::postProcess(const ProcessArgs& args) { } bool DADSRHPlus::shouldTriggerOnNextLoad() { - for (int c = 0; c < maxChannels; ++c) { - if (_core[c] && _core[c]->_stage != _core[c]->STOPPED_STAGE) { + for (int c = 0; c < _channels; ++c) { + if (_core[c]->_stage != _core[c]->STOPPED_STAGE) { return true; } } diff --git a/src/DGate.cpp b/src/DGate.cpp @@ -11,10 +11,8 @@ void DGate::Engine::reset() { } void DGate::reset() { - for (int c = 0; c < maxChannels; ++c) { - if (_engines[c]) { - _engines[c]->reset(); - } + for (int c = 0; c < _channels; ++c) { + _engines[c]->reset(); } } @@ -33,36 +31,38 @@ void DGate::removeEngine(int c) { } void DGate::processChannel(const ProcessArgs& args, int c) { + Engine& e = *_engines[c]; + float envelope = 0.0; bool complete = false; if ( - _engines[c]->trigger.process(params[TRIGGER_PARAM].getValue() + inputs[TRIGGER_INPUT].getPolyVoltage(c)) || - (_engines[c]->firstStep && _triggerOnLoad && _shouldTriggerOnLoad && params[LOOP_PARAM].getValue() <= 0.0) + e.trigger.process(params[TRIGGER_PARAM].getValue() + inputs[TRIGGER_INPUT].getPolyVoltage(c)) || + (e.firstStep && _triggerOnLoad && _shouldTriggerOnLoad && params[LOOP_PARAM].getValue() <= 0.0) ) { - _engines[c]->stage = DELAY_STAGE; - _engines[c]->stageProgress = 0.0; + e.stage = DELAY_STAGE; + e.stageProgress = 0.0; } else { - switch (_engines[c]->stage) { + switch (e.stage) { case STOPPED_STAGE: { break; } case DELAY_STAGE: { if (stepStage(c, params[DELAY_PARAM])) { - _engines[c]->stage = GATE_STAGE; - _engines[c]->stageProgress = 0.0; + e.stage = GATE_STAGE; + e.stageProgress = 0.0; } break; } case GATE_STAGE: { if (stepStage(c, params[GATE_PARAM])) { complete = true; - if (params[LOOP_PARAM].getValue() <= 0.0 || _engines[c]->trigger.isHigh()) { - _engines[c]->stage = DELAY_STAGE; - _engines[c]->stageProgress = 0.0; + if (params[LOOP_PARAM].getValue() <= 0.0 || e.trigger.isHigh()) { + e.stage = DELAY_STAGE; + e.stageProgress = 0.0; } else { - _engines[c]->stage = STOPPED_STAGE; + e.stage = STOPPED_STAGE; } } else { @@ -76,25 +76,23 @@ void DGate::processChannel(const ProcessArgs& args, int c) { outputs[GATE_OUTPUT].setChannels(_channels); outputs[GATE_OUTPUT].setVoltage(envelope * 10.0, c); if (complete) { - _engines[c]->triggerOuptutPulseGen.trigger(0.001); + e.triggerOuptutPulseGen.trigger(0.001); } outputs[END_OUTPUT].setChannels(_channels); - outputs[END_OUTPUT].setVoltage(_engines[c]->triggerOuptutPulseGen.process(APP->engine->getSampleTime()) ? 5.0 : 0.0, c); + outputs[END_OUTPUT].setVoltage(e.triggerOuptutPulseGen.process(APP->engine->getSampleTime()) ? 5.0 : 0.0, c); - _engines[c]->delayLight = _engines[c]->stage == DELAY_STAGE; - _engines[c]->gateLight = _engines[c]->stage == GATE_STAGE; + e.delayLight = e.stage == DELAY_STAGE; + e.gateLight = e.stage == GATE_STAGE; - _engines[c]->firstStep = false; + e.firstStep = false; } void DGate::postProcess(const ProcessArgs& args) { float delaySum = 0.0f; float gateSum = 0.0f; - for (int c = 0; c < maxChannels; ++c) { - if (_engines[c]) { - delaySum += _engines[c]->delayLight; - gateSum += _engines[c]->gateLight; - } + for (int c = 0; c < _channels; ++c) { + delaySum += _engines[c]->delayLight; + gateSum += _engines[c]->gateLight; } lights[DELAY_LIGHT].value = delaySum / (float)_channels; lights[GATE_LIGHT].value = gateSum / (float)_channels; @@ -109,8 +107,8 @@ bool DGate::stepStage(int c, Param& knob) { } bool DGate::shouldTriggerOnNextLoad() { - for (int c = 0; c < maxChannels; ++c) { - if (_engines[c] && _engines[c]->stage != STOPPED_STAGE) { + for (int c = 0; c < _channels; ++c) { + if (_engines[c]->stage != STOPPED_STAGE) { return true; } } diff --git a/src/EightFO.cpp b/src/EightFO.cpp @@ -21,18 +21,14 @@ void EightFO::Engine::sampleRateChange() { } void EightFO::reset() { - for (int c = 0; c < maxChannels; ++c) { - if (_engines[c]) { - _engines[c]->reset(); - } + for (int c = 0; c < _channels; ++c) { + _engines[c]->reset(); } } void EightFO::sampleRateChange() { - for (int c = 0; c < maxChannels; ++c) { - if (_engines[c]) { - _engines[c]->sampleRateChange(); - } + for (int c = 0; c < _channels; ++c) { + _engines[c]->sampleRateChange(); } } @@ -69,47 +65,49 @@ void EightFO::modulate() { } void EightFO::modulateChannel(int c) { - setFrequency(params[FREQUENCY_PARAM], inputs[PITCH_INPUT], _engines[c]->phasor, c); + Engine& e = *_engines[c]; + + setFrequency(params[FREQUENCY_PARAM], inputs[PITCH_INPUT], e.phasor, c); if (_wave == SQUARE_WAVE) { float pw = params[SAMPLE_PWM_PARAM].getValue(); if (inputs[SAMPLE_PWM_INPUT].isConnected()) { pw *= clamp(inputs[SAMPLE_PWM_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); } - pw *= 1.0f - 2.0f * _engines[c]->square.minPulseWidth; + pw *= 1.0f - 2.0f * e.square.minPulseWidth; pw *= 0.5f; pw += 0.5f; - _engines[c]->square.setPulseWidth(pw); - _engines[c]->sampleSteps = 1; + e.square.setPulseWidth(pw); + e.sampleSteps = 1; } else { float sample = fabsf(params[SAMPLE_PWM_PARAM].getValue()); if (inputs[SAMPLE_PWM_INPUT].isConnected()) { sample *= clamp(fabsf(inputs[SAMPLE_PWM_INPUT].getPolyVoltage(c)) / 5.0f, 0.0f, 1.0f); } - float maxSampleSteps = (_engines[c]->phasor._sampleRate / _engines[c]->phasor._frequency) / 4.0f; - _engines[c]->sampleSteps = clamp((int)(sample * maxSampleSteps), 1, (int)maxSampleSteps); - _engines[c]->square.setPulseWidth(SquareOscillator::defaultPulseWidth); + float maxSampleSteps = (e.phasor._sampleRate / e.phasor._frequency) / 4.0f; + e.sampleSteps = clamp((int)(sample * maxSampleSteps), 1, (int)maxSampleSteps); + e.square.setPulseWidth(SquareOscillator::defaultPulseWidth); } - _engines[c]->offset = params[OFFSET_PARAM].getValue(); + e.offset = params[OFFSET_PARAM].getValue(); if (inputs[OFFSET_INPUT].isConnected()) { - _engines[c]->offset *= clamp(inputs[OFFSET_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); + e.offset *= clamp(inputs[OFFSET_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); } - _engines[c]->offset *= 5.0f; - _engines[c]->scale = params[SCALE_PARAM].getValue(); + e.offset *= 5.0f; + e.scale = params[SCALE_PARAM].getValue(); if (inputs[SCALE_INPUT].isConnected()) { - _engines[c]->scale *= clamp(inputs[SCALE_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); + e.scale *= clamp(inputs[SCALE_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } - _engines[c]->phase7Offset = phaseOffset(c, params[PHASE7_PARAM], inputs[PHASE7_INPUT], basePhase7Offset); - _engines[c]->phase6Offset = phaseOffset(c, params[PHASE6_PARAM], inputs[PHASE6_INPUT], basePhase6Offset); - _engines[c]->phase5Offset = phaseOffset(c, params[PHASE5_PARAM], inputs[PHASE5_INPUT], basePhase5Offset); - _engines[c]->phase4Offset = phaseOffset(c, params[PHASE4_PARAM], inputs[PHASE4_INPUT], basePhase4Offset); - _engines[c]->phase3Offset = phaseOffset(c, params[PHASE3_PARAM], inputs[PHASE3_INPUT], basePhase3Offset); - _engines[c]->phase2Offset = phaseOffset(c, params[PHASE2_PARAM], inputs[PHASE2_INPUT], basePhase2Offset); - _engines[c]->phase1Offset = phaseOffset(c, params[PHASE1_PARAM], inputs[PHASE1_INPUT], basePhase1Offset); - _engines[c]->phase0Offset = phaseOffset(c, params[PHASE0_PARAM], inputs[PHASE0_INPUT], basePhase0Offset); + e.phase7Offset = phaseOffset(c, params[PHASE7_PARAM], inputs[PHASE7_INPUT], basePhase7Offset); + e.phase6Offset = phaseOffset(c, params[PHASE6_PARAM], inputs[PHASE6_INPUT], basePhase6Offset); + e.phase5Offset = phaseOffset(c, params[PHASE5_PARAM], inputs[PHASE5_INPUT], basePhase5Offset); + e.phase4Offset = phaseOffset(c, params[PHASE4_PARAM], inputs[PHASE4_INPUT], basePhase4Offset); + e.phase3Offset = phaseOffset(c, params[PHASE3_PARAM], inputs[PHASE3_INPUT], basePhase3Offset); + e.phase2Offset = phaseOffset(c, params[PHASE2_PARAM], inputs[PHASE2_INPUT], basePhase2Offset); + e.phase1Offset = phaseOffset(c, params[PHASE1_PARAM], inputs[PHASE1_INPUT], basePhase1Offset); + e.phase0Offset = phaseOffset(c, params[PHASE0_PARAM], inputs[PHASE0_INPUT], basePhase0Offset); } void EightFO::always(const ProcessArgs& args) { @@ -117,29 +115,31 @@ void EightFO::always(const ProcessArgs& args) { } void EightFO::processChannel(const ProcessArgs& args, int c) { - if (_engines[c]->resetTrigger.next(inputs[RESET_INPUT].getPolyVoltage(c))) { - _engines[c]->phasor.resetPhase(); + Engine& e = *_engines[c]; + + if (e.resetTrigger.next(inputs[RESET_INPUT].getPolyVoltage(c))) { + e.phasor.resetPhase(); } - _engines[c]->phasor.advancePhase(); + e.phasor.advancePhase(); bool useSample = false; - if (_engines[c]->sampleSteps > 1) { - ++_engines[c]->sampleStep; - if (_engines[c]->sampleStep >= _engines[c]->sampleSteps) { - _engines[c]->sampleStep = 0; + if (e.sampleSteps > 1) { + ++e.sampleStep; + if (e.sampleStep >= e.sampleSteps) { + e.sampleStep = 0; } else { useSample = true; } } - updateOutput(c, useSample, outputs[PHASE7_OUTPUT], _engines[c]->phase7Offset, _engines[c]->phase7Sample, _engines[c]->phase7Active); - updateOutput(c, useSample, outputs[PHASE6_OUTPUT], _engines[c]->phase6Offset, _engines[c]->phase6Sample, _engines[c]->phase6Active); - updateOutput(c, useSample, outputs[PHASE5_OUTPUT], _engines[c]->phase5Offset, _engines[c]->phase5Sample, _engines[c]->phase5Active); - updateOutput(c, useSample, outputs[PHASE4_OUTPUT], _engines[c]->phase4Offset, _engines[c]->phase4Sample, _engines[c]->phase4Active); - updateOutput(c, useSample, outputs[PHASE3_OUTPUT], _engines[c]->phase3Offset, _engines[c]->phase3Sample, _engines[c]->phase3Active); - updateOutput(c, useSample, outputs[PHASE2_OUTPUT], _engines[c]->phase2Offset, _engines[c]->phase2Sample, _engines[c]->phase2Active); - updateOutput(c, useSample, outputs[PHASE1_OUTPUT], _engines[c]->phase1Offset, _engines[c]->phase1Sample, _engines[c]->phase1Active); - updateOutput(c, useSample, outputs[PHASE0_OUTPUT], _engines[c]->phase0Offset, _engines[c]->phase0Sample, _engines[c]->phase0Active); + updateOutput(c, useSample, outputs[PHASE7_OUTPUT], e.phase7Offset, e.phase7Sample, e.phase7Active); + updateOutput(c, useSample, outputs[PHASE6_OUTPUT], e.phase6Offset, e.phase6Sample, e.phase6Active); + updateOutput(c, useSample, outputs[PHASE5_OUTPUT], e.phase5Offset, e.phase5Sample, e.phase5Active); + updateOutput(c, useSample, outputs[PHASE4_OUTPUT], e.phase4Offset, e.phase4Sample, e.phase4Active); + updateOutput(c, useSample, outputs[PHASE3_OUTPUT], e.phase3Offset, e.phase3Sample, e.phase3Active); + updateOutput(c, useSample, outputs[PHASE2_OUTPUT], e.phase2Offset, e.phase2Sample, e.phase2Active); + updateOutput(c, useSample, outputs[PHASE1_OUTPUT], e.phase1Offset, e.phase1Sample, e.phase1Active); + updateOutput(c, useSample, outputs[PHASE0_OUTPUT], e.phase0Offset, e.phase0Sample, e.phase0Active); } Phasor::phase_delta_t EightFO::phaseOffset(int c, Param& p, Input& i, Phasor::phase_delta_t baseOffset) { diff --git a/src/Follow.cpp b/src/Follow.cpp @@ -2,10 +2,8 @@ #include "Follow.hpp" void Follow::sampleRateChange() { - for (int c = 0; c < maxChannels; ++c) { - if (_rms[c]) { - _rms[c]->setSampleRate(APP->engine->getSampleRate()); - } + for (int c = 0; c < _channels; ++c) { + _rms[c]->setSampleRate(APP->engine->getSampleRate()); } } diff --git a/src/LFO.cpp b/src/LFO.cpp @@ -12,18 +12,14 @@ void LFO::Engine::sampleRateChange() { } void LFO::reset() { - for (int c = 0; c < maxChannels; ++c) { - if (_engines[c]) { - _engines[c]->reset(); - } + for (int c = 0; c < _channels; ++c) { + _engines[c]->reset(); } } void LFO::sampleRateChange() { - for (int c = 0; c < maxChannels; ++c) { - if (_engines[c]) { - _engines[c]->sampleRateChange(); - } + for (int c = 0; c < _channels; ++c) { + _engines[c]->sampleRateChange(); } } @@ -53,33 +49,35 @@ void LFO::removeEngine(int c) { } void LFO::modulateChannel(int c) { - setFrequency(params[FREQUENCY_PARAM], inputs[PITCH_INPUT], _engines[c]->phasor, c); + Engine& e = *_engines[c]; + + setFrequency(params[FREQUENCY_PARAM], inputs[PITCH_INPUT], e.phasor, c); float pw = params[PW_PARAM].getValue(); if (inputs[PW_INPUT].isConnected()) { pw *= clamp(inputs[PW_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); } - pw *= 1.0f - 2.0f * _engines[c]->square.minPulseWidth; + pw *= 1.0f - 2.0f * e.square.minPulseWidth; pw *= 0.5f; pw += 0.5f; - _engines[c]->square.setPulseWidth(pw); + e.square.setPulseWidth(pw); float sample = params[SAMPLE_PARAM].getValue(); if (inputs[SAMPLE_INPUT].isConnected()) { sample *= clamp(inputs[SAMPLE_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } - float maxSampleSteps = (_engines[c]->phasor._sampleRate / _engines[c]->phasor._frequency) / 4.0f; - _engines[c]->sampleSteps = clamp((int)(sample * maxSampleSteps), 1, (int)maxSampleSteps); + float maxSampleSteps = (e.phasor._sampleRate / e.phasor._frequency) / 4.0f; + e.sampleSteps = clamp((int)(sample * maxSampleSteps), 1, (int)maxSampleSteps); - _engines[c]->offset = params[OFFSET_PARAM].getValue(); + e.offset = params[OFFSET_PARAM].getValue(); if (inputs[OFFSET_INPUT].isConnected()) { - _engines[c]->offset *= clamp(inputs[OFFSET_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); + e.offset *= clamp(inputs[OFFSET_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); } - _engines[c]->offset *= 5.0f; + e.offset *= 5.0f; - _engines[c]->scale = params[SCALE_PARAM].getValue(); + e.scale = params[SCALE_PARAM].getValue(); if (inputs[SCALE_INPUT].isConnected()) { - _engines[c]->scale *= clamp(inputs[SCALE_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); + e.scale *= clamp(inputs[SCALE_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } } @@ -88,26 +86,28 @@ void LFO::always(const ProcessArgs& args) { } void LFO::processChannel(const ProcessArgs& args, int c) { - if (_engines[c]->resetTrigger.next(inputs[RESET_INPUT].getPolyVoltage(c))) { - _engines[c]->phasor.resetPhase(); + Engine& e = *_engines[c]; + + if (e.resetTrigger.next(inputs[RESET_INPUT].getPolyVoltage(c))) { + e.phasor.resetPhase(); } - _engines[c]->phasor.advancePhase(); + e.phasor.advancePhase(); bool useSample = false; - if (_engines[c]->sampleSteps > 1) { - ++_engines[c]->sampleStep; - if (_engines[c]->sampleStep >= _engines[c]->sampleSteps) { - _engines[c]->sampleStep = 0; + if (e.sampleSteps > 1) { + ++e.sampleStep; + if (e.sampleStep >= e.sampleSteps) { + e.sampleStep = 0; } else { useSample = true; } } - updateOutput(c, _engines[c]->sine, useSample, false, outputs[SINE_OUTPUT], _engines[c]->sineSample, _engines[c]->sineActive); - updateOutput(c, _engines[c]->triangle, useSample, false, outputs[TRIANGLE_OUTPUT], _engines[c]->triangleSample, _engines[c]->triangleActive); - updateOutput(c, _engines[c]->ramp, useSample, false, outputs[RAMP_UP_OUTPUT], _engines[c]->rampUpSample, _engines[c]->rampUpActive); - updateOutput(c, _engines[c]->ramp, useSample, true, outputs[RAMP_DOWN_OUTPUT], _engines[c]->rampDownSample, _engines[c]->rampDownActive); - updateOutput(c, _engines[c]->square, false, false, outputs[SQUARE_OUTPUT], _engines[c]->squareSample, _engines[c]->squareActive); + updateOutput(c, e.sine, useSample, false, outputs[SINE_OUTPUT], e.sineSample, e.sineActive); + updateOutput(c, e.triangle, useSample, false, outputs[TRIANGLE_OUTPUT], e.triangleSample, e.triangleActive); + updateOutput(c, e.ramp, useSample, false, outputs[RAMP_UP_OUTPUT], e.rampUpSample, e.rampUpActive); + updateOutput(c, e.ramp, useSample, true, outputs[RAMP_DOWN_OUTPUT], e.rampDownSample, e.rampDownActive); + updateOutput(c, e.square, false, false, outputs[SQUARE_OUTPUT], e.squareSample, e.squareActive); } void LFO::updateOutput(int c, Phasor& wave, bool useSample, bool invert, Output& output, float& sample, bool& active) { diff --git a/src/Lmtr.cpp b/src/Lmtr.cpp @@ -3,12 +3,10 @@ void Lmtr::sampleRateChange() { float sampleRate = APP->engine->getSampleRate(); - for (int i = 0; i < _channels; ++i) { - if (_engines[i]) { - _engines[i]->detector.setSampleRate(sampleRate); - _engines[i]->attackSL.setParams(sampleRate, 150.0f); - _engines[i]->releaseSL.setParams(sampleRate, 600.0f); - } + for (int c = 0; c < _channels; ++c) { + _engines[c]->detector.setSampleRate(sampleRate); + _engines[c]->attackSL.setParams(sampleRate, 150.0f); + _engines[c]->releaseSL.setParams(sampleRate, 600.0f); } } @@ -34,54 +32,58 @@ void Lmtr::modulate() { } void Lmtr::modulateChannel(int c) { + Engine& e = *_engines[c]; + if (!_engines[c]) { return; } - _engines[c]->thresholdDb = params[THRESHOLD_PARAM].getValue(); + e.thresholdDb = params[THRESHOLD_PARAM].getValue(); if (inputs[THRESHOLD_INPUT].isConnected()) { - _engines[c]->thresholdDb *= clamp(inputs[THRESHOLD_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); + e.thresholdDb *= clamp(inputs[THRESHOLD_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } - _engines[c]->thresholdDb *= 30.0f; - _engines[c]->thresholdDb -= 24.0f; + e.thresholdDb *= 30.0f; + e.thresholdDb -= 24.0f; float outGain = params[OUTPUT_GAIN_PARAM].getValue(); if (inputs[OUTPUT_GAIN_INPUT].isConnected()) { outGain = clamp(outGain + inputs[OUTPUT_GAIN_INPUT].getPolyVoltage(c) / 5.0f, 0.0f, 1.0f); } outGain *= 24.0f; - if (_engines[c]->outGain != outGain) { - _engines[c]->outGain = outGain; - _engines[c]->outLevel = decibelsToAmplitude(_engines[c]->outGain); + if (e.outGain != outGain) { + e.outGain = outGain; + e.outLevel = decibelsToAmplitude(e.outGain); } } void Lmtr::processChannel(const ProcessArgs& args, int c) { + Engine& e = *_engines[c]; + if (!_engines[c]) { return; } float leftInput = inputs[LEFT_INPUT].getPolyVoltage(c); float rightInput = inputs[RIGHT_INPUT].getPolyVoltage(c); - float env = _engines[c]->detector.next(leftInput + rightInput); - if (env > _engines[c]->lastEnv) { - env = _engines[c]->attackSL.next(env, _engines[c]->lastEnv); + float env = e.detector.next(leftInput + rightInput); + if (env > e.lastEnv) { + env = e.attackSL.next(env, e.lastEnv); } else { - env = _engines[c]->releaseSL.next(env, _engines[c]->lastEnv); + env = e.releaseSL.next(env, e.lastEnv); } - _engines[c]->lastEnv = env; + e.lastEnv = env; float detectorDb = amplitudeToDecibels(env / 5.0f); - float compressionDb = _engines[c]->compressor.compressionDb(detectorDb, _engines[c]->thresholdDb, Compressor::maxEffectiveRatio, _softKnee); - _engines[c]->amplifier.setLevel(-compressionDb); + float compressionDb = e.compressor.compressionDb(detectorDb, e.thresholdDb, Compressor::maxEffectiveRatio, _softKnee); + e.amplifier.setLevel(-compressionDb); if (outputs[LEFT_OUTPUT].isConnected()) { outputs[LEFT_OUTPUT].setChannels(_channels); - outputs[LEFT_OUTPUT].setVoltage(_engines[c]->saturator.next(_engines[c]->amplifier.next(leftInput) * _engines[c]->outLevel), c); + outputs[LEFT_OUTPUT].setVoltage(e.saturator.next(e.amplifier.next(leftInput) * e.outLevel), c); } if (outputs[RIGHT_OUTPUT].isConnected()) { outputs[RIGHT_OUTPUT].setChannels(_channels); - outputs[RIGHT_OUTPUT].setVoltage(_engines[c]->saturator.next(_engines[c]->amplifier.next(rightInput) * _engines[c]->outLevel), c); + outputs[RIGHT_OUTPUT].setVoltage(e.saturator.next(e.amplifier.next(rightInput) * e.outLevel), c); } } diff --git a/src/Nsgt.cpp b/src/Nsgt.cpp @@ -4,12 +4,10 @@ void Nsgt::sampleRateChange() { float sampleRate = APP->engine->getSampleRate(); - for (int i = 0; i < _channels; ++i) { - if (_engines[i]) { - _engines[i]->detector.setSampleRate(sampleRate); - _engines[i]->attackSL.setParams(sampleRate, 150.0f); - _engines[i]->releaseSL.setParams(sampleRate, 600.0f); - } + for (int c = 0; c < _channels; ++c) { + _engines[c]->detector.setSampleRate(sampleRate); + _engines[c]->attackSL.setParams(sampleRate, 150.0f); + _engines[c]->releaseSL.setParams(sampleRate, 600.0f); } } @@ -35,59 +33,63 @@ void Nsgt::modulate() { } void Nsgt::modulateChannel(int c) { + Engine& e = *_engines[c]; + if (!_engines[c]) { return; } - _engines[c]->thresholdDb = params[THRESHOLD_PARAM].getValue(); + e.thresholdDb = params[THRESHOLD_PARAM].getValue(); if (inputs[THRESHOLD_INPUT].isConnected()) { - _engines[c]->thresholdDb *= clamp(inputs[THRESHOLD_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); + e.thresholdDb *= clamp(inputs[THRESHOLD_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } - _engines[c]->thresholdDb *= 30.0f; - _engines[c]->thresholdDb -= 24.0f; + e.thresholdDb *= 30.0f; + e.thresholdDb -= 24.0f; float ratio = params[RATIO_PARAM].getValue(); if (inputs[RATIO_INPUT].isConnected()) { ratio *= clamp(inputs[RATIO_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } - if (_engines[c]->ratioKnob != ratio) { - _engines[c]->ratioKnob = ratio; - ratio = powf(_engines[c]->ratioKnob, 1.5f); + if (e.ratioKnob != ratio) { + e.ratioKnob = ratio; + ratio = powf(e.ratioKnob, 1.5f); ratio = 1.0f - ratio; ratio *= M_PI; ratio *= 0.25f; ratio = tanf(ratio); ratio = 1.0f / ratio; - _engines[c]->ratioKnob = ratio; + e.ratioKnob = ratio; } } void Nsgt::processChannel(const ProcessArgs& args, int c) { + Engine& e = *_engines[c]; + if (!_engines[c]) { return; } float leftInput = inputs[LEFT_INPUT].getPolyVoltage(c); float rightInput = inputs[RIGHT_INPUT].getPolyVoltage(c); - float env = _engines[c]->detector.next(leftInput + rightInput); - if (env > _engines[c]->lastEnv) { - env = _engines[c]->attackSL.next(env, _engines[c]->lastEnv); + float env = e.detector.next(leftInput + rightInput); + if (env > e.lastEnv) { + env = e.attackSL.next(env, e.lastEnv); } else { - env = _engines[c]->releaseSL.next(env, _engines[c]->lastEnv); + env = e.releaseSL.next(env, e.lastEnv); } - _engines[c]->lastEnv = env; + e.lastEnv = env; float detectorDb = amplitudeToDecibels(env / 5.0f); - float compressionDb = _engines[c]->noiseGate.compressionDb(detectorDb, _engines[c]->thresholdDb, _engines[c]->ratio, _softKnee); - _engines[c]->amplifier.setLevel(-compressionDb); + float compressionDb = e.noiseGate.compressionDb(detectorDb, e.thresholdDb, e.ratio, _softKnee); + e.amplifier.setLevel(-compressionDb); if (outputs[LEFT_OUTPUT].isConnected()) { outputs[LEFT_OUTPUT].setChannels(_channels); - outputs[LEFT_OUTPUT].setVoltage(_engines[c]->saturator.next(_engines[c]->amplifier.next(leftInput)), c); + outputs[LEFT_OUTPUT].setVoltage(e.saturator.next(e.amplifier.next(leftInput)), c); } if (outputs[RIGHT_OUTPUT].isConnected()) { outputs[RIGHT_OUTPUT].setChannels(_channels); - outputs[RIGHT_OUTPUT].setVoltage(_engines[c]->saturator.next(_engines[c]->amplifier.next(rightInput)), c); + outputs[RIGHT_OUTPUT].setVoltage(e.saturator.next(e.amplifier.next(rightInput)), c); } } diff --git a/src/Pressor.cpp b/src/Pressor.cpp @@ -2,10 +2,8 @@ #include "Pressor.hpp" void Pressor::sampleRateChange() { - for (int i = 0; i < maxChannels; ++i) { - if (_engines[i]) { - _engines[i]->detectorRMS.setSampleRate(APP->engine->getSampleRate()); - } + for (int c = 0; c < _channels; ++c) { + _engines[c]->detectorRMS.setSampleRate(APP->engine->getSampleRate()); } } @@ -40,30 +38,32 @@ void Pressor::modulate() { } void Pressor::modulateChannel(int c) { + Engine& e = *_engines[c]; + if (!_engines[c]) { return; } - _engines[c]->thresholdDb = params[THRESHOLD_PARAM].getValue(); + e.thresholdDb = params[THRESHOLD_PARAM].getValue(); if (inputs[THRESHOLD_INPUT].isConnected()) { - _engines[c]->thresholdDb *= clamp(inputs[THRESHOLD_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); + e.thresholdDb *= clamp(inputs[THRESHOLD_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } - _engines[c]->thresholdDb *= 30.0f; - _engines[c]->thresholdDb -= 24.0f; + e.thresholdDb *= 30.0f; + e.thresholdDb -= 24.0f; float ratio = params[RATIO_PARAM].getValue(); if (inputs[RATIO_INPUT].isConnected()) { ratio *= clamp(inputs[RATIO_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } - if (_engines[c]->ratioKnob != ratio) { - _engines[c]->ratioKnob = ratio; + if (e.ratioKnob != ratio) { + e.ratioKnob = ratio; ratio = powf(ratio, 1.5f); ratio = 1.0f - ratio; ratio *= M_PI; ratio *= 0.25f; ratio = tanf(ratio); ratio = 1.0f / ratio; - _engines[c]->ratio = ratio; + e.ratio = ratio; } float sampleRate = APP->engine->getSampleRate(); @@ -72,23 +72,23 @@ void Pressor::modulateChannel(int c) { attack *= clamp(inputs[ATTACK_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } attack *= attack; - _engines[c]->attackSL.setParams(sampleRate, attack * 500.0f); + e.attackSL.setParams(sampleRate, attack * 500.0f); float release = params[RELEASE_PARAM].getValue(); if (inputs[RELEASE_INPUT].isConnected()) { release *= clamp(inputs[RELEASE_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } release *= release; - _engines[c]->releaseSL.setParams(sampleRate, release * 2000.0f); + e.releaseSL.setParams(sampleRate, release * 2000.0f); float inGain = params[INPUT_GAIN_PARAM].getValue(); if (inputs[INPUT_GAIN_INPUT].isConnected()) { inGain = clamp(inGain + inputs[INPUT_GAIN_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); } inGain *= 12.0f; - if (_engines[c]->inGain != inGain) { - _engines[c]->inGain = inGain; - _engines[c]->inLevel = decibelsToAmplitude(_engines[c]->inGain); + if (e.inGain != inGain) { + e.inGain = inGain; + e.inLevel = decibelsToAmplitude(e.inGain); } float outGain = params[OUTPUT_GAIN_PARAM].getValue(); @@ -96,48 +96,50 @@ void Pressor::modulateChannel(int c) { outGain = clamp(outGain + inputs[OUTPUT_GAIN_INPUT].getPolyVoltage(c) / 5.0f, 0.0f, 1.0f); } outGain *= 24.0f; - if (_engines[c]->outGain != outGain) { - _engines[c]->outGain = outGain; - _engines[c]->outLevel = decibelsToAmplitude(_engines[c]->outGain); + if (e.outGain != outGain) { + e.outGain = outGain; + e.outLevel = decibelsToAmplitude(e.outGain); } - _engines[c]->detectorMix.setParams(params[DETECTOR_MIX_PARAM].getValue(), 0.0f, true); + e.detectorMix.setParams(params[DETECTOR_MIX_PARAM].getValue(), 0.0f, true); } void Pressor::processChannel(const ProcessArgs& args, int c) { + Engine& e = *_engines[c]; + if (!_engines[c]) { return; } - float leftInput = inputs[LEFT_INPUT].getPolyVoltage(c) * _engines[c]->inLevel; - float rightInput = inputs[RIGHT_INPUT].getPolyVoltage(c) * _engines[c]->inLevel; + float leftInput = inputs[LEFT_INPUT].getPolyVoltage(c) * e.inLevel; + float rightInput = inputs[RIGHT_INPUT].getPolyVoltage(c) * e.inLevel; float env = leftInput + rightInput; if (inputs[SIDECHAIN_INPUT].isConnected()) { - env = _engines[c]->detectorMix.next(env, inputs[SIDECHAIN_INPUT].getPolyVoltage(c)); + env = e.detectorMix.next(env, inputs[SIDECHAIN_INPUT].getPolyVoltage(c)); } if (_rmsDetector) { - env = _engines[c]->detectorRMS.next(env); + env = e.detectorRMS.next(env); } else { env = fabsf(env); } - if (env > _engines[c]->lastEnv) { - env = _engines[c]->attackSL.next(env, _engines[c]->lastEnv); + if (env > e.lastEnv) { + env = e.attackSL.next(env, e.lastEnv); } else { - env = _engines[c]->releaseSL.next(env, _engines[c]->lastEnv); + env = e.releaseSL.next(env, e.lastEnv); } - _engines[c]->lastEnv = env; + e.lastEnv = env; float detectorDb = amplitudeToDecibels(env / 5.0f); float compressionDb = 0.0f; if (_compressorMode) { - compressionDb = _engines[c]->compressor.compressionDb(detectorDb, _engines[c]->thresholdDb, _engines[c]->ratio, _softKnee); + compressionDb = e.compressor.compressionDb(detectorDb, e.thresholdDb, e.ratio, _softKnee); } else { - compressionDb = _engines[c]->noiseGate.compressionDb(detectorDb, _engines[c]->thresholdDb, _engines[c]->ratio, _softKnee); + compressionDb = e.noiseGate.compressionDb(detectorDb, e.thresholdDb, e.ratio, _softKnee); } - _engines[c]->amplifier.setLevel(-compressionDb); + e.amplifier.setLevel(-compressionDb); if (c == 0) { _compressionDb = compressionDb; outputs[ENVELOPE_OUTPUT].setChannels(_channels); @@ -146,10 +148,10 @@ void Pressor::processChannel(const ProcessArgs& args, int c) { } outputs[ENVELOPE_OUTPUT].setVoltage(env, c); if (outputs[LEFT_OUTPUT].isConnected()) { - outputs[LEFT_OUTPUT].setVoltage(_engines[c]->saturator.next(_engines[c]->amplifier.next(leftInput) * _engines[c]->outLevel), c); + outputs[LEFT_OUTPUT].setVoltage(e.saturator.next(e.amplifier.next(leftInput) * e.outLevel), c); } if (outputs[RIGHT_OUTPUT].isConnected()) { - outputs[RIGHT_OUTPUT].setVoltage(_engines[c]->saturator.next(_engines[c]->amplifier.next(rightInput) * _engines[c]->outLevel), c); + outputs[RIGHT_OUTPUT].setVoltage(e.saturator.next(e.amplifier.next(rightInput) * e.outLevel), c); } } diff --git a/src/Shaper.cpp b/src/Shaper.cpp @@ -2,10 +2,8 @@ #include "Shaper.hpp" void Shaper::reset() { - for (int c = 0; c < maxChannels; ++c) { - if (_core[c]) { - _core[c]->reset(); - } + for (int c = 0; c < _channels; ++c) { + _core[c]->reset(); } } @@ -67,13 +65,11 @@ void Shaper::postProcess(const ProcessArgs& args) { float onSum = 0.0f; float decaySum = 0.0f; float offSum = 0.0f; - for (int c = 0; c < maxChannels; ++c) { - if (_core[c]) { - attackSum += _attackLights[c]; - onSum += _onLights[c]; - decaySum += _decayLights[c]; - offSum += _offLights[c]; - } + for (int c = 0; c < _channels; ++c) { + attackSum += _attackLights[c]; + onSum += _onLights[c]; + decaySum += _decayLights[c]; + offSum += _offLights[c]; } lights[ATTACK_LIGHT].value = attackSum / (float)_channels; lights[ON_LIGHT].value = onSum / (float)_channels; @@ -82,8 +78,8 @@ void Shaper::postProcess(const ProcessArgs& args) { } bool Shaper::shouldTriggerOnNextLoad() { - for (int c = 0; c < maxChannels; ++c) { - if (_core[c] && _core[c]->_stage != _core[c]->STOPPED_STAGE) { + for (int c = 0; c < _channels; ++c) { + if (_core[c]->_stage != _core[c]->STOPPED_STAGE) { return true; } } diff --git a/src/ShaperPlus.cpp b/src/ShaperPlus.cpp @@ -2,10 +2,8 @@ #include "ShaperPlus.hpp" void ShaperPlus::reset() { - for (int c = 0; c < maxChannels; ++c) { - if (_core[c]) { - _core[c]->reset(); - } + for (int c = 0; c < _channels; ++c) { + _core[c]->reset(); } } @@ -67,13 +65,11 @@ void ShaperPlus::postProcess(const ProcessArgs& args) { float onSum = 0.0f; float decaySum = 0.0f; float offSum = 0.0f; - for (int c = 0; c < maxChannels; ++c) { - if (_core[c]) { - attackSum += _attackLights[c]; - onSum += _onLights[c]; - decaySum += _decayLights[c]; - offSum += _offLights[c]; - } + for (int c = 0; c < _channels; ++c) { + attackSum += _attackLights[c]; + onSum += _onLights[c]; + decaySum += _decayLights[c]; + offSum += _offLights[c]; } lights[ATTACK_LIGHT].value = attackSum / (float)_channels; lights[ON_LIGHT].value = onSum / (float)_channels; @@ -82,8 +78,8 @@ void ShaperPlus::postProcess(const ProcessArgs& args) { } bool ShaperPlus::shouldTriggerOnNextLoad() { - for (int c = 0; c < maxChannels; ++c) { - if (_core[c] && _core[c]->_stage != _core[c]->STOPPED_STAGE) { + for (int c = 0; c < _channels; ++c) { + if (_core[c]->_stage != _core[c]->STOPPED_STAGE) { return true; } } diff --git a/src/VCO.cpp b/src/VCO.cpp @@ -31,10 +31,8 @@ void VCO::Engine::setFrequency(float f) { } void VCO::reset() { - for (int c = 0; c < maxChannels; ++c) { - if (_engines[c]) { - _engines[c]->reset(); - } + for (int c = 0; c < _channels; ++c) { + _engines[c]->reset(); } } @@ -42,10 +40,8 @@ void VCO::sampleRateChange() { float sampleRate = APP->engine->getSampleRate(); _oversampleThreshold = 0.06f * sampleRate; - for (int c = 0; c < maxChannels; ++c) { - if (_engines[c]) { - _engines[c]->sampleRateChange(sampleRate); - } + for (int c = 0; c < _channels; ++c) { + _engines[c]->sampleRateChange(sampleRate); } } @@ -79,24 +75,26 @@ void VCO::modulate() { } void VCO::modulateChannel(int c) { - _engines[c]->baseVOct = params[FREQUENCY_PARAM].getValue(); - _engines[c]->baseVOct += params[FINE_PARAM].getValue() / 12.0f; + Engine& e = *_engines[c]; + + e.baseVOct = params[FREQUENCY_PARAM].getValue(); + e.baseVOct += params[FINE_PARAM].getValue() / 12.0f; if (inputs[PITCH_INPUT].isConnected()) { - _engines[c]->baseVOct += clamp(inputs[PITCH_INPUT].getVoltage(c), -5.0f, 5.0f); + e.baseVOct += clamp(inputs[PITCH_INPUT].getVoltage(c), -5.0f, 5.0f); } if (_slowMode) { - _engines[c]->baseVOct += slowModeOffset; + e.baseVOct += slowModeOffset; } - _engines[c]->baseHz = cvToFrequency(_engines[c]->baseVOct); + e.baseHz = cvToFrequency(e.baseVOct); float pw = params[PW_PARAM].getValue(); if (inputs[PW_INPUT].isConnected()) { pw *= clamp(inputs[PW_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); } - pw *= 1.0f - 2.0f * _engines[c]->square.minPulseWidth; + pw *= 1.0f - 2.0f * e.square.minPulseWidth; pw *= 0.5f; pw += 0.5f; - _engines[c]->square.setPulseWidth(_engines[c]->squarePulseWidthSL.next(pw)); + e.square.setPulseWidth(e.squarePulseWidthSL.next(pw)); } void VCO::always(const ProcessArgs& args) { @@ -104,11 +102,13 @@ void VCO::always(const ProcessArgs& args) { } void VCO::processChannel(const ProcessArgs& args, int c) { - if (_engines[c]->syncTrigger.next(inputs[SYNC_INPUT].getPolyVoltage(c))) { - _engines[c]->phasor.resetPhase(); + Engine& e = *_engines[c]; + + if (e.syncTrigger.next(inputs[SYNC_INPUT].getPolyVoltage(c))) { + e.phasor.resetPhase(); } - float frequency = _engines[c]->baseHz; + float frequency = e.baseHz; Phasor::phase_delta_t phaseOffset = 0; if (inputs[FM_INPUT].isConnected() && _fmDepth > 0.01f) { float fm = inputs[FM_INPUT].getPolyVoltage(c) * _fmDepth; @@ -116,10 +116,10 @@ void VCO::processChannel(const ProcessArgs& args, int c) { phaseOffset = Phasor::radiansToPhase(2.0f * fm); } else { - frequency = cvToFrequency(_engines[c]->baseVOct + fm); + frequency = cvToFrequency(e.baseVOct + fm); } } - _engines[c]->setFrequency(frequency); + e.setFrequency(frequency); const float oversampleWidth = 100.0f; float mix, oMix; @@ -143,39 +143,39 @@ void VCO::processChannel(const ProcessArgs& args, int c) { float triangleOut = 0.0f; if (oMix > 0.0f) { for (int i = 0; i < Engine::oversample; ++i) { - _engines[c]->phasor.advancePhase(); + e.phasor.advancePhase(); if (outputs[SQUARE_OUTPUT].isConnected()) { - _engines[c]->squareBuffer[i] = _engines[c]->square.nextFromPhasor(_engines[c]->phasor, phaseOffset); + e.squareBuffer[i] = e.square.nextFromPhasor(e.phasor, phaseOffset); } if (outputs[SAW_OUTPUT].isConnected()) { - _engines[c]->sawBuffer[i] = _engines[c]->saw.nextFromPhasor(_engines[c]->phasor, phaseOffset); + e.sawBuffer[i] = e.saw.nextFromPhasor(e.phasor, phaseOffset); } if (outputs[TRIANGLE_OUTPUT].isConnected()) { - _engines[c]->triangleBuffer[i] = _engines[c]->triangle.nextFromPhasor(_engines[c]->phasor, phaseOffset); + e.triangleBuffer[i] = e.triangle.nextFromPhasor(e.phasor, phaseOffset); } } if (outputs[SQUARE_OUTPUT].isConnected()) { - squareOut += oMix * amplitude * _engines[c]->squareDecimator.next(_engines[c]->squareBuffer); + squareOut += oMix * amplitude * e.squareDecimator.next(e.squareBuffer); } if (outputs[SAW_OUTPUT].isConnected()) { - sawOut += oMix * amplitude * _engines[c]->sawDecimator.next(_engines[c]->sawBuffer); + sawOut += oMix * amplitude * e.sawDecimator.next(e.sawBuffer); } if (outputs[TRIANGLE_OUTPUT].isConnected()) { - triangleOut += oMix * amplitude * _engines[c]->triangleDecimator.next(_engines[c]->triangleBuffer); + triangleOut += oMix * amplitude * e.triangleDecimator.next(e.triangleBuffer); } } else { - _engines[c]->phasor.advancePhase(Engine::oversample); + e.phasor.advancePhase(Engine::oversample); } if (mix > 0.0f) { if (outputs[SQUARE_OUTPUT].isConnected()) { - squareOut += mix * amplitude * _engines[c]->square.nextFromPhasor(_engines[c]->phasor, phaseOffset); + squareOut += mix * amplitude * e.square.nextFromPhasor(e.phasor, phaseOffset); } if (outputs[SAW_OUTPUT].isConnected()) { - sawOut += mix * amplitude * _engines[c]->saw.nextFromPhasor(_engines[c]->phasor, phaseOffset); + sawOut += mix * amplitude * e.saw.nextFromPhasor(e.phasor, phaseOffset); } if (outputs[TRIANGLE_OUTPUT].isConnected()) { - triangleOut += mix * amplitude * _engines[c]->triangle.nextFromPhasor(_engines[c]->phasor, phaseOffset); + triangleOut += mix * amplitude * e.triangle.nextFromPhasor(e.phasor, phaseOffset); } } @@ -186,7 +186,7 @@ void VCO::processChannel(const ProcessArgs& args, int c) { outputs[TRIANGLE_OUTPUT].setChannels(_channels); outputs[TRIANGLE_OUTPUT].setVoltage(triangleOut, c); outputs[SINE_OUTPUT].setChannels(_channels); - outputs[SINE_OUTPUT].setVoltage(outputs[SINE_OUTPUT].isConnected() ? (amplitude * _engines[c]->sine.nextFromPhasor(_engines[c]->phasor, phaseOffset)) : 0.0f, c); + outputs[SINE_OUTPUT].setVoltage(outputs[SINE_OUTPUT].isConnected() ? (amplitude * e.sine.nextFromPhasor(e.phasor, phaseOffset)) : 0.0f, c); } struct VCOWidget : ModuleWidget { diff --git a/src/XCO.cpp b/src/XCO.cpp @@ -42,10 +42,8 @@ void XCO::Engine::setFrequency(float f) { } void XCO::reset() { - for (int c = 0; c < maxChannels; ++c) { - if (_engines[c]) { - _engines[c]->reset(); - } + for (int c = 0; c < _channels; ++c) { + _engines[c]->reset(); } } @@ -53,10 +51,8 @@ void XCO::sampleRateChange() { float sampleRate = APP->engine->getSampleRate(); _oversampleThreshold = 0.06f * sampleRate; - for (int c = 0; c < maxChannels; ++c) { - if (_engines[c]) { - _engines[c]->sampleRateChange(sampleRate); - } + for (int c = 0; c < _channels; ++c) { + _engines[c]->sampleRateChange(sampleRate); } } @@ -90,58 +86,60 @@ void XCO::modulate() { } void XCO::modulateChannel(int c) { - _engines[c]->baseVOct = params[FREQUENCY_PARAM].getValue(); - _engines[c]->baseVOct += params[FINE_PARAM].getValue() / 12.0f;; + Engine& e = *_engines[c]; + + e.baseVOct = params[FREQUENCY_PARAM].getValue(); + e.baseVOct += params[FINE_PARAM].getValue() / 12.0f;; if (inputs[PITCH_INPUT].isConnected()) { - _engines[c]->baseVOct += clamp(inputs[PITCH_INPUT].getVoltage(c), -5.0f, 5.0f); + e.baseVOct += clamp(inputs[PITCH_INPUT].getVoltage(c), -5.0f, 5.0f); } if (_slowMode) { - _engines[c]->baseVOct += _slowModeOffset; + e.baseVOct += _slowModeOffset; } - _engines[c]->baseHz = cvToFrequency(_engines[c]->baseVOct); + e.baseHz = cvToFrequency(e.baseVOct); float pw = params[SQUARE_PW_PARAM].getValue(); if (inputs[SQUARE_PW_INPUT].isConnected()) { pw *= clamp(inputs[SQUARE_PW_INPUT].getPolyVoltage(c) / 5.0f, -1.0f, 1.0f); } - pw *= 1.0f - 2.0f * _engines[c]->square.minPulseWidth; + pw *= 1.0f - 2.0f * e.square.minPulseWidth; pw *= 0.5f; pw += 0.5f; - _engines[c]->square.setPulseWidth(_engines[c]->squarePulseWidthSL.next(pw)); + e.square.setPulseWidth(e.squarePulseWidthSL.next(pw)); float saturation = params[SAW_SATURATION_PARAM].getValue(); if (inputs[SAW_SATURATION_INPUT].isConnected()) { saturation *= clamp(inputs[SAW_SATURATION_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } - _engines[c]->saw.setSaturation(_engines[c]->sawSaturationSL.next(saturation) * 10.f); + e.saw.setSaturation(e.sawSaturationSL.next(saturation) * 10.f); float tsw = params[TRIANGLE_SAMPLE_PARAM].getValue() * Phasor::maxSampleWidth; if (inputs[TRIANGLE_SAMPLE_INPUT].isConnected()) { tsw *= clamp(inputs[TRIANGLE_SAMPLE_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } - _engines[c]->triangleSampleWidth = _engines[c]->triangleSampleWidthSL.next(tsw); - _engines[c]->triangle.setSampleWidth(_engines[c]->triangleSampleWidth); + e.triangleSampleWidth = e.triangleSampleWidthSL.next(tsw); + e.triangle.setSampleWidth(e.triangleSampleWidth); float sfb = params[SINE_FEEDBACK_PARAM].getValue(); if (inputs[SINE_FEEDBACK_INPUT].isConnected()) { sfb *= clamp(inputs[SINE_FEEDBACK_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } - _engines[c]->sineFeedback = _engines[c]->sineFeedbackSL.next(sfb); + e.sineFeedback = e.sineFeedbackSL.next(sfb); - _engines[c]->fmDepth = params[FM_DEPTH_PARAM].getValue(); + e.fmDepth = params[FM_DEPTH_PARAM].getValue(); if (inputs[FM_DEPTH_INPUT].isConnected()) { - _engines[c]->fmDepth *= clamp(inputs[FM_DEPTH_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); + e.fmDepth *= clamp(inputs[FM_DEPTH_INPUT].getPolyVoltage(c) / 10.0f, 0.0f, 1.0f); } - _engines[c]->squarePhaseOffset = phaseOffset(c, params[SQUARE_PHASE_PARAM], inputs[SQUARE_PHASE_INPUT]); - _engines[c]->sawPhaseOffset = phaseOffset(c, params[SAW_PHASE_PARAM], inputs[SAW_PHASE_INPUT]); - _engines[c]->trianglePhaseOffset = phaseOffset(c, params[TRIANGLE_PHASE_PARAM], inputs[TRIANGLE_PHASE_INPUT]); - _engines[c]->sinePhaseOffset = phaseOffset(c, params[SINE_PHASE_PARAM], inputs[SINE_PHASE_INPUT]); + e.squarePhaseOffset = phaseOffset(c, params[SQUARE_PHASE_PARAM], inputs[SQUARE_PHASE_INPUT]); + e.sawPhaseOffset = phaseOffset(c, params[SAW_PHASE_PARAM], inputs[SAW_PHASE_INPUT]); + e.trianglePhaseOffset = phaseOffset(c, params[TRIANGLE_PHASE_PARAM], inputs[TRIANGLE_PHASE_INPUT]); + e.sinePhaseOffset = phaseOffset(c, params[SINE_PHASE_PARAM], inputs[SINE_PHASE_INPUT]); - _engines[c]->squareMix = level(c, params[SQUARE_MIX_PARAM], inputs[SQUARE_MIX_INPUT]); - _engines[c]->sawMix = level(c, params[SAW_MIX_PARAM], inputs[SAW_MIX_INPUT]); - _engines[c]->triangleMix = level(c, params[TRIANGLE_MIX_PARAM], inputs[TRIANGLE_MIX_INPUT]); - _engines[c]->sineMix = level(c, params[SINE_MIX_PARAM], inputs[SINE_MIX_INPUT]); + e.squareMix = level(c, params[SQUARE_MIX_PARAM], inputs[SQUARE_MIX_INPUT]); + e.sawMix = level(c, params[SAW_MIX_PARAM], inputs[SAW_MIX_INPUT]); + e.triangleMix = level(c, params[TRIANGLE_MIX_PARAM], inputs[TRIANGLE_MIX_INPUT]); + e.sineMix = level(c, params[SINE_MIX_PARAM], inputs[SINE_MIX_INPUT]); } void XCO::always(const ProcessArgs& args) { @@ -149,23 +147,25 @@ void XCO::always(const ProcessArgs& args) { } void XCO::processChannel(const ProcessArgs& args, int c) { - if (_engines[c]->syncTrigger.next(inputs[SYNC_INPUT].getPolyVoltage(c))) { - _engines[c]->phasor.resetPhase(); + Engine& e = *_engines[c]; + + if (e.syncTrigger.next(inputs[SYNC_INPUT].getPolyVoltage(c))) { + e.phasor.resetPhase(); } - float frequency = _engines[c]->baseHz; + float frequency = e.baseHz; Phasor::phase_delta_t phaseOffset = 0; - float fmd = _engines[c]->fmDepthSL.next(_engines[c]->fmDepth); + float fmd = e.fmDepthSL.next(e.fmDepth); if (inputs[FM_INPUT].isConnected() && fmd > 0.01f) { float fm = inputs[FM_INPUT].getPolyVoltage(c) * fmd; if (_fmLinearMode) { phaseOffset = Phasor::radiansToPhase(2.0f * fm); } else { - frequency = cvToFrequency(_engines[c]->baseVOct + fm); + frequency = cvToFrequency(e.baseVOct + fm); } } - _engines[c]->setFrequency(frequency); + e.setFrequency(frequency); const float oversampleWidth = 100.0f; float mix, oMix; @@ -184,7 +184,7 @@ void XCO::processChannel(const ProcessArgs& args, int c) { oMix = 0.0f; } - bool triangleSample = _engines[c]->triangleSampleWidth > 0.001f; + bool triangleSample = e.triangleSampleWidth > 0.001f; bool squareActive = outputs[MIX_OUTPUT].isConnected() || outputs[SQUARE_OUTPUT].isConnected(); bool sawActive = outputs[MIX_OUTPUT].isConnected() || outputs[SAW_OUTPUT].isConnected(); bool triangleActive = outputs[MIX_OUTPUT].isConnected() || outputs[TRIANGLE_OUTPUT].isConnected(); @@ -202,64 +202,64 @@ void XCO::processChannel(const ProcessArgs& args, int c) { Phasor::phase_delta_t sineFeedbackOffset = 0; if (sineActive) { - if (_engines[c]->sineFeedback > 0.001f) { - sineFeedbackOffset = Phasor::radiansToPhase(_engines[c]->sineFeedback * _engines[c]->sineFeedbackDelayedSample); - if (_engines[c]->sineOMix < 1.0f) { - _engines[c]->sineOMix += sineOversampleMixIncrement; + if (e.sineFeedback > 0.001f) { + sineFeedbackOffset = Phasor::radiansToPhase(e.sineFeedback * e.sineFeedbackDelayedSample); + if (e.sineOMix < 1.0f) { + e.sineOMix += sineOversampleMixIncrement; } } - else if (_engines[c]->sineOMix > 0.0f) { - _engines[c]->sineOMix -= sineOversampleMixIncrement; + else if (e.sineOMix > 0.0f) { + e.sineOMix -= sineOversampleMixIncrement; } } - if (squareOversample || sawOversample || triangleOversample || _engines[c]->sineOMix > 0.0f) { + if (squareOversample || sawOversample || triangleOversample || e.sineOMix > 0.0f) { for (int i = 0; i < Engine::oversample; ++i) { - _engines[c]->phasor.advancePhase(); + e.phasor.advancePhase(); if (squareOversample) { - _engines[c]->squareBuffer[i] = _engines[c]->square.nextFromPhasor(_engines[c]->phasor, _engines[c]->squarePhaseOffset + phaseOffset); + e.squareBuffer[i] = e.square.nextFromPhasor(e.phasor, e.squarePhaseOffset + phaseOffset); } if (sawOversample) { - _engines[c]->sawBuffer[i] = _engines[c]->saw.nextFromPhasor(_engines[c]->phasor, _engines[c]->sawPhaseOffset + phaseOffset); + e.sawBuffer[i] = e.saw.nextFromPhasor(e.phasor, e.sawPhaseOffset + phaseOffset); } if (triangleOversample) { - _engines[c]->triangleBuffer[i] = _engines[c]->triangle.nextFromPhasor(_engines[c]->phasor, _engines[c]->trianglePhaseOffset + phaseOffset); + e.triangleBuffer[i] = e.triangle.nextFromPhasor(e.phasor, e.trianglePhaseOffset + phaseOffset); } - if (_engines[c]->sineOMix > 0.0f) { - _engines[c]->sineBuffer[i] = _engines[c]->sine.nextFromPhasor(_engines[c]->phasor, sineFeedbackOffset + _engines[c]->sinePhaseOffset + phaseOffset); + if (e.sineOMix > 0.0f) { + e.sineBuffer[i] = e.sine.nextFromPhasor(e.phasor, sineFeedbackOffset + e.sinePhaseOffset + phaseOffset); } } if (squareOversample) { - squareOut += oMix * amplitude * _engines[c]->squareDecimator.next(_engines[c]->squareBuffer); + squareOut += oMix * amplitude * e.squareDecimator.next(e.squareBuffer); } if (sawOversample) { - sawOut += oMix * amplitude * _engines[c]->sawDecimator.next(_engines[c]->sawBuffer); + sawOut += oMix * amplitude * e.sawDecimator.next(e.sawBuffer); } if (triangleOversample) { - triangleOut += amplitude * _engines[c]->triangleDecimator.next(_engines[c]->triangleBuffer); + triangleOut += amplitude * e.triangleDecimator.next(e.triangleBuffer); if (!triangleSample) { triangleOut *= oMix; } } - if (_engines[c]->sineOMix > 0.0f) { - sineOut += amplitude * _engines[c]->sineOMix * _engines[c]->sineDecimator.next(_engines[c]->sineBuffer); + if (e.sineOMix > 0.0f) { + sineOut += amplitude * e.sineOMix * e.sineDecimator.next(e.sineBuffer); } } else { - _engines[c]->phasor.advancePhase(Engine::oversample); + e.phasor.advancePhase(Engine::oversample); } if (squareNormal) { - squareOut += mix * amplitude * _engines[c]->square.nextFromPhasor(_engines[c]->phasor, _engines[c]->squarePhaseOffset + phaseOffset); + squareOut += mix * amplitude * e.square.nextFromPhasor(e.phasor, e.squarePhaseOffset + phaseOffset); } if (sawNormal) { - sawOut += mix * amplitude * _engines[c]->saw.nextFromPhasor(_engines[c]->phasor, _engines[c]->sawPhaseOffset + phaseOffset); + sawOut += mix * amplitude * e.saw.nextFromPhasor(e.phasor, e.sawPhaseOffset + phaseOffset); } if (triangleNormal) { - triangleOut += mix * amplitude * _engines[c]->triangle.nextFromPhasor(_engines[c]->phasor, _engines[c]->trianglePhaseOffset + phaseOffset); + triangleOut += mix * amplitude * e.triangle.nextFromPhasor(e.phasor, e.trianglePhaseOffset + phaseOffset); } - if (_engines[c]->sineOMix < 1.0f) { - sineOut += amplitude * (1.0f - _engines[c]->sineOMix) * _engines[c]->sine.nextFromPhasor(_engines[c]->phasor, sineFeedbackOffset + _engines[c]->sinePhaseOffset + phaseOffset); + if (e.sineOMix < 1.0f) { + sineOut += amplitude * (1.0f - e.sineOMix) * e.sine.nextFromPhasor(e.phasor, sineFeedbackOffset + e.sinePhaseOffset + phaseOffset); } outputs[SQUARE_OUTPUT].setChannels(_channels); @@ -269,12 +269,12 @@ void XCO::processChannel(const ProcessArgs& args, int c) { outputs[TRIANGLE_OUTPUT].setChannels(_channels); outputs[TRIANGLE_OUTPUT].setVoltage(triangleOut, c); outputs[SINE_OUTPUT].setChannels(_channels); - outputs[SINE_OUTPUT].setVoltage(_engines[c]->sineFeedbackDelayedSample = sineOut, c); + outputs[SINE_OUTPUT].setVoltage(e.sineFeedbackDelayedSample = sineOut, c); if (outputs[MIX_OUTPUT].isConnected()) { - float mix = _engines[c]->squareMixSL.next(_engines[c]->squareMix) * squareOut; - mix += _engines[c]->sawMixSL.next(_engines[c]->sawMix) * sawOut; - mix += _engines[c]->triangleMixSL.next(_engines[c]->triangleMix) * triangleOut; - mix += _engines[c]->sineMixSL.next(_engines[c]->sineMix) * sineOut; + float mix = e.squareMixSL.next(e.squareMix) * squareOut; + mix += e.sawMixSL.next(e.sawMix) * sawOut; + mix += e.triangleMixSL.next(e.triangleMix) * triangleOut; + mix += e.sineMixSL.next(e.sineMix) * sineOut; outputs[MIX_OUTPUT].setChannels(_channels); outputs[MIX_OUTPUT].setVoltage(mix, c); }