commit df847e4aec2584f1ef30cd6eb70c0e661066e1a5
parent 53d8f31000d0c9e12c3733d6a2c65b3a0e1569c2
Author: Matt Demanett <matt@demanett.net>
Date: Sun, 19 Apr 2020 01:38:18 -0400
Speed up MIX4/8; drastically speed up their expanders.
Diffstat:
8 files changed, 312 insertions(+), 183 deletions(-)
diff --git a/src/Mix4.cpp b/src/Mix4.cpp
@@ -34,6 +34,24 @@ void Mix4::processAll(const ProcessArgs& args) {
fromExp = fromExpander();
}
+ if (!(
+ inputs[IN1_INPUT].isConnected() ||
+ inputs[IN2_INPUT].isConnected() ||
+ inputs[IN3_INPUT].isConnected() ||
+ inputs[IN4_INPUT].isConnected()
+ )) {
+ if (_wasActive > 0) {
+ --_wasActive;
+ for (int i = 0; i < 4; ++i) {
+ _channels[i]->reset();
+ toExp->active[i] = false;
+ }
+ _rmsLevel = 0.0f;
+ }
+ return;
+ }
+ _wasActive = 2;
+
bool solo =
params[MUTE1_PARAM].getValue() > 1.5f ||
params[MUTE2_PARAM].getValue() > 1.5f ||
@@ -48,18 +66,23 @@ void Mix4::processAll(const ProcessArgs& args) {
sample = inputs[IN1_INPUT].getVoltageSum();
}
_channels[0]->next(sample, solo);
- toExp->preFader[0] = sample;
+ toExp->active[0] = inputs[IN1_INPUT].isConnected();
for (int i = 1; i < 4; ++i) {
float sample = 0.0f;
+ bool channelActive = false;
if (inputs[IN1_INPUT + 3 * i].isConnected()) {
sample = inputs[IN1_INPUT + 3 * i].getVoltageSum();
+ _channels[i]->next(sample, solo);
+ channelActive = true;
}
else if (_polyChannelOffset >= 0) {
sample = inputs[IN1_INPUT].getPolyVoltage(_polyChannelOffset + i);
+ _channels[i]->next(sample, solo);
+ channelActive = true;
}
- _channels[i]->next(sample, solo);
toExp->preFader[i] = sample;
+ toExp->active[i] = channelActive;
}
}
@@ -243,6 +266,12 @@ void Mix4x::sampleRateChange() {
_returnBSL.setParams(sr, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
}
+void Mix4x::modulate() {
+ for (int i = 0; i < 4; ++i) {
+ _channels[i]->modulate();
+ }
+}
+
void Mix4x::processAll(const ProcessArgs& args) {
if (!baseConnected()) {
outputs[SEND_A_OUTPUT].setVoltage(0.0f);
@@ -254,50 +283,65 @@ void Mix4x::processAll(const ProcessArgs& args) {
Mix4ExpanderMessage* to = toBase();
float sendA = 0.0f;
float sendB = 0.0f;
+ bool sendAActive = outputs[SEND_A_OUTPUT].isConnected();
+ bool sendBActive = outputs[SEND_B_OUTPUT].isConnected();
for (int i = 0; i < 4; ++i) {
- _channels[i]->next(from->preFader[i], from->postFader[i]);
- to->postEQ[i] = _channels[i]->postEQ;
- sendA += _channels[i]->sendA;
- sendB += _channels[i]->sendB;
+ if (from->active[i]) {
+ _channels[i]->next(from->preFader[i], from->postFader[i], sendAActive, sendBActive);
+ to->postEQ[i] = _channels[i]->postEQ;
+ sendA += _channels[i]->sendA;
+ sendB += _channels[i]->sendB;
+ }
+ else {
+ to->postEQ[i] = from->preFader[i];
+ }
}
outputs[SEND_A_OUTPUT].setVoltage(_saturatorA.next(sendA));
outputs[SEND_B_OUTPUT].setVoltage(_saturatorA.next(sendB));
- float levelA = clamp(params[LEVEL_A_PARAM].getValue(), 0.0f, 1.0f);
- if (inputs[LEVEL_A_INPUT].isConnected()) {
- levelA *= clamp(inputs[LEVEL_A_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f);
- }
- levelA = 1.0f - levelA;
- levelA *= Amplifier::minDecibels;
- _returnAAmp.setLevel(_returnASL.next(levelA));
- if (inputs[L_A_INPUT].isConnected()) {
- to->returnA[0] = _returnAAmp.next(inputs[L_A_INPUT].getVoltage());
- }
- else {
- to->returnA[0] = 0.0f;
- }
- if (inputs[R_A_INPUT].isConnected()) {
- to->returnA[1] = _returnAAmp.next(inputs[R_A_INPUT].getVoltage());
- }
- else {
- to->returnA[1] = to->returnA[0];
+ bool lAActive = inputs[L_A_INPUT].isConnected();
+ bool rAActive = inputs[R_A_INPUT].isConnected();
+ if (lAActive || rAActive) {
+ float levelA = clamp(params[LEVEL_A_PARAM].getValue(), 0.0f, 1.0f);
+ if (inputs[LEVEL_A_INPUT].isConnected()) {
+ levelA *= clamp(inputs[LEVEL_A_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f);
+ }
+ levelA = 1.0f - levelA;
+ levelA *= Amplifier::minDecibels;
+ _returnAAmp.setLevel(_returnASL.next(levelA));
+ if (lAActive) {
+ to->returnA[0] = _returnAAmp.next(inputs[L_A_INPUT].getVoltage());
+ }
+ else {
+ to->returnA[0] = 0.0f;
+ }
+ if (rAActive) {
+ to->returnA[1] = _returnAAmp.next(inputs[R_A_INPUT].getVoltage());
+ }
+ else {
+ to->returnA[1] = to->returnA[0];
+ }
}
- float levelB = clamp(params[LEVEL_B_PARAM].getValue(), 0.0f, 1.0f);
- levelB = 1.0f - levelB;
- levelB *= Amplifier::minDecibels;
- _returnBAmp.setLevel(_returnBSL.next(levelB));
- if (inputs[L_B_INPUT].isConnected()) {
- to->returnB[0] = _returnBAmp.next(inputs[L_B_INPUT].getVoltage());
- }
- else {
- to->returnB[0] = 0.0f;
- }
- if (inputs[R_B_INPUT].isConnected()) {
- to->returnB[1] = _returnBAmp.next(inputs[R_B_INPUT].getVoltage());
- }
- else {
- to->returnB[1] = to->returnB[0];
+ bool lBActive = inputs[L_B_INPUT].isConnected();
+ bool rBActive = inputs[R_B_INPUT].isConnected();
+ if (lBActive || rBActive) {
+ float levelB = clamp(params[LEVEL_B_PARAM].getValue(), 0.0f, 1.0f);
+ levelB = 1.0f - levelB;
+ levelB *= Amplifier::minDecibels;
+ _returnBAmp.setLevel(_returnBSL.next(levelB));
+ if (lBActive) {
+ to->returnB[0] = _returnBAmp.next(inputs[L_B_INPUT].getVoltage());
+ }
+ else {
+ to->returnB[0] = 0.0f;
+ }
+ if (rBActive) {
+ to->returnB[1] = _returnBAmp.next(inputs[R_B_INPUT].getVoltage());
+ }
+ else {
+ to->returnB[1] = to->returnB[0];
+ }
}
}
diff --git a/src/Mix4.hpp b/src/Mix4.hpp
@@ -1,7 +1,7 @@
#pragma once
#include "bogaudio.hpp"
-#include "mixer.hpp"
+#include "mixer_expander.hpp"
#include "dsp/signal.hpp"
using namespace bogaudio::dsp;
@@ -67,6 +67,7 @@ struct Mix4 : ExpandableModule<Mix4ExpanderMessage, BGModule> {
RootMeanSquare _rms;
float _rmsLevel = 0.0f;
Mix4ExpanderMessage _dummyExpanderMessage;
+ int _wasActive = 0;
Mix4() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
@@ -217,6 +218,7 @@ struct Mix4x : ExpanderModule<Mix4ExpanderMessage, BGModule> {
}
void sampleRateChange() override;
+ void modulate() override;
void processAll(const ProcessArgs& args) override;
};
diff --git a/src/Mix8.cpp b/src/Mix8.cpp
@@ -34,6 +34,28 @@ void Mix8::processAll(const ProcessArgs& args) {
fromExp = fromExpander();
}
+ if (!(
+ inputs[IN1_INPUT].isConnected() ||
+ inputs[IN2_INPUT].isConnected() ||
+ inputs[IN3_INPUT].isConnected() ||
+ inputs[IN4_INPUT].isConnected() ||
+ inputs[IN5_INPUT].isConnected() ||
+ inputs[IN6_INPUT].isConnected() ||
+ inputs[IN7_INPUT].isConnected() ||
+ inputs[IN8_INPUT].isConnected()
+ )) {
+ if (_wasActive > 0) {
+ --_wasActive;
+ for (int i = 0; i < 8; ++i) {
+ _channels[i]->reset();
+ toExp->active[i] = false;
+ }
+ _rmsLevel = 0.0f;
+ }
+ return;
+ }
+ _wasActive = 2;
+
bool solo =
params[MUTE1_PARAM].getValue() > 1.5f ||
params[MUTE2_PARAM].getValue() > 1.5f ||
@@ -53,17 +75,27 @@ void Mix8::processAll(const ProcessArgs& args) {
}
_channels[0]->next(sample, solo);
toExp->preFader[0] = sample;
+ toExp->active[0] = inputs[IN1_INPUT].isConnected();
for (int i = 1; i < 8; ++i) {
float sample = 0.0f;
+ bool channelActive = false;
if (inputs[IN1_INPUT + 3 * i].isConnected()) {
sample = inputs[IN1_INPUT + 3 * i].getVoltageSum();
+ _channels[i]->next(sample, solo);
+ channelActive = true;
}
else if (_polyChannelOffset >= 0) {
sample = inputs[IN1_INPUT].getPolyVoltage(_polyChannelOffset + i);
+ _channels[i]->next(sample, solo);
+ channelActive = true;
+ }
+ else {
+ _channels[i]->out = 0.0f;
+ _channels[i]->rms = 0.0f;
}
- _channels[i]->next(sample, solo);
toExp->preFader[i] = sample;
+ toExp->active[i] = channelActive;
}
}
@@ -293,6 +325,12 @@ void Mix8x::sampleRateChange() {
_returnBSL.setParams(sr, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
}
+void Mix8x::modulate() {
+ for (int i = 0; i < 8; ++i) {
+ _channels[i]->modulate();
+ }
+}
+
void Mix8x::processAll(const ProcessArgs& args) {
if (!baseConnected()) {
outputs[SEND_A_OUTPUT].setVoltage(0.0f);
@@ -304,50 +342,65 @@ void Mix8x::processAll(const ProcessArgs& args) {
Mix8ExpanderMessage* to = toBase();
float sendA = 0.0f;
float sendB = 0.0f;
+ bool sendAActive = outputs[SEND_A_OUTPUT].isConnected();
+ bool sendBActive = outputs[SEND_B_OUTPUT].isConnected();
for (int i = 0; i < 8; ++i) {
- _channels[i]->next(from->preFader[i], from->postFader[i]);
- to->postEQ[i] = _channels[i]->postEQ;
- sendA += _channels[i]->sendA;
- sendB += _channels[i]->sendB;
+ if (from->active[i]) {
+ _channels[i]->next(from->preFader[i], from->postFader[i], sendAActive, sendBActive);
+ to->postEQ[i] = _channels[i]->postEQ;
+ sendA += _channels[i]->sendA;
+ sendB += _channels[i]->sendB;
+ }
+ else {
+ to->postEQ[i] = from->preFader[i];
+ }
}
outputs[SEND_A_OUTPUT].setVoltage(_saturatorA.next(sendA));
outputs[SEND_B_OUTPUT].setVoltage(_saturatorA.next(sendB));
- float levelA = clamp(params[LEVEL_A_PARAM].getValue(), 0.0f, 1.0f);
- if (inputs[LEVEL_A_INPUT].isConnected()) {
- levelA *= clamp(inputs[LEVEL_A_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f);
- }
- levelA = 1.0f - levelA;
- levelA *= Amplifier::minDecibels;
- _returnAAmp.setLevel(_returnASL.next(levelA));
- if (inputs[L_A_INPUT].isConnected()) {
- to->returnA[0] = _returnAAmp.next(inputs[L_A_INPUT].getVoltage());
- }
- else {
- to->returnA[0] = 0.0f;
- }
- if (inputs[R_A_INPUT].isConnected()) {
- to->returnA[1] = _returnAAmp.next(inputs[R_A_INPUT].getVoltage());
- }
- else {
- to->returnA[1] = to->returnA[0];
+ bool lAActive = inputs[L_A_INPUT].isConnected();
+ bool rAActive = inputs[R_A_INPUT].isConnected();
+ if (lAActive || rAActive) {
+ float levelA = clamp(params[LEVEL_A_PARAM].getValue(), 0.0f, 1.0f);
+ if (inputs[LEVEL_A_INPUT].isConnected()) {
+ levelA *= clamp(inputs[LEVEL_A_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f);
+ }
+ levelA = 1.0f - levelA;
+ levelA *= Amplifier::minDecibels;
+ _returnAAmp.setLevel(_returnASL.next(levelA));
+ if (lAActive) {
+ to->returnA[0] = _returnAAmp.next(inputs[L_A_INPUT].getVoltage());
+ }
+ else {
+ to->returnA[0] = 0.0f;
+ }
+ if (rAActive) {
+ to->returnA[1] = _returnAAmp.next(inputs[R_A_INPUT].getVoltage());
+ }
+ else {
+ to->returnA[1] = to->returnA[0];
+ }
}
- float levelB = clamp(params[LEVEL_B_PARAM].getValue(), 0.0f, 1.0f);
- levelB = 1.0f - levelB;
- levelB *= Amplifier::minDecibels;
- _returnBAmp.setLevel(_returnBSL.next(levelB));
- if (inputs[L_B_INPUT].isConnected()) {
- to->returnB[0] = _returnBAmp.next(inputs[L_B_INPUT].getVoltage());
- }
- else {
- to->returnB[0] = 0.0f;
- }
- if (inputs[R_B_INPUT].isConnected()) {
- to->returnB[1] = _returnBAmp.next(inputs[R_B_INPUT].getVoltage());
- }
- else {
- to->returnB[1] = to->returnB[0];
+ bool lBActive = inputs[L_B_INPUT].isConnected();
+ bool rBActive = inputs[R_B_INPUT].isConnected();
+ if (lBActive || rBActive) {
+ float levelB = clamp(params[LEVEL_B_PARAM].getValue(), 0.0f, 1.0f);
+ levelB = 1.0f - levelB;
+ levelB *= Amplifier::minDecibels;
+ _returnBAmp.setLevel(_returnBSL.next(levelB));
+ if (lBActive) {
+ to->returnB[0] = _returnBAmp.next(inputs[L_B_INPUT].getVoltage());
+ }
+ else {
+ to->returnB[0] = 0.0f;
+ }
+ if (rBActive) {
+ to->returnB[1] = _returnBAmp.next(inputs[R_B_INPUT].getVoltage());
+ }
+ else {
+ to->returnB[1] = to->returnB[0];
+ }
}
}
diff --git a/src/Mix8.hpp b/src/Mix8.hpp
@@ -1,7 +1,7 @@
#pragma once
#include "bogaudio.hpp"
-#include "mixer.hpp"
+#include "mixer_expander.hpp"
#include "dsp/signal.hpp"
using namespace bogaudio::dsp;
@@ -91,6 +91,7 @@ struct Mix8 : ExpandableModule<Mix8ExpanderMessage, BGModule> {
RootMeanSquare _rms;
float _rmsLevel = 0.0f;
Mix8ExpanderMessage _dummyExpanderMessage;
+ int _wasActive = 0;
Mix8() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
@@ -325,6 +326,7 @@ struct Mix8x : ExpanderModule<Mix8ExpanderMessage, BGModule> {
}
void sampleRateChange() override;
+ void modulate() override;
void processAll(const ProcessArgs& args) override;
};
diff --git a/src/mixer.cpp b/src/mixer.cpp
@@ -10,6 +10,10 @@ void MixerChannel::setSampleRate(float sampleRate) {
_rms.setSampleRate(sampleRate);
}
+void MixerChannel::reset() {
+ out = rms = 0.0f;
+}
+
void MixerChannel::next(float sample, bool solo, int c) {
float mute = _muteParam.getValue();
if (_muteInput) {
@@ -34,48 +38,6 @@ void MixerChannel::next(float sample, bool solo, int c) {
}
-void MixerExpanderChannel::setSampleRate(float sampleRate) {
- _sendASL.setParams(sampleRate, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
- _sendBSL.setParams(sampleRate, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
-}
-
-float MixerExpanderChannel::knobToDb(Param& p) {
- float v = clamp(p.getValue(), -1.0f, 1.0f);
- if (v < 0.0f) {
- return -v * Equalizer::cutDb;
- }
- return v * Equalizer::gainDb;
-}
-
-void MixerExpanderChannel::next(float preFader, float postFader) {
- _eq.setParams(
- APP->engine->getSampleRate(),
- knobToDb(_lowParam),
- knobToDb(_midParam),
- knobToDb(_highParam)
- );
- postEQ = _eq.next(postFader);
-
- float level = clamp(_sendAParam.getValue(), 0.0f, 1.0f);
- if (_sendAInput.isConnected()) {
- level *= clamp(_sendAInput.getVoltage() / 10.0f, 0.0f, 1.0f);
- }
- level = 1.0f - level;
- level *= Amplifier::minDecibels;
- _sendAAmp.setLevel(_sendASL.next(level));
- sendA = _sendAAmp.next(_preAParam.getValue() > 0.5f ? preFader : postEQ);
-
- level = clamp(_sendBParam.getValue(), 0.0f, 1.0f);
- if (_sendBInput.isConnected()) {
- level *= clamp(_sendBInput.getVoltage() / 10.0f, 0.0f, 1.0f);
- }
- level = 1.0f - level;
- level *= Amplifier::minDecibels;
- _sendBAmp.setLevel(_sendBSL.next(level));
- sendB = _sendBAmp.next(_preBParam.getValue() > 0.5f ? preFader : postEQ);
-}
-
-
void MuteButton::onButton(const event::Button& e) {
if (!(e.action == GLFW_PRESS && (e.mods & RACK_MOD_MASK) == 0)) {
return;
diff --git a/src/mixer.hpp b/src/mixer.hpp
@@ -1,8 +1,6 @@
#pragma once
#include "bogaudio.hpp"
-#include "expanders.hpp"
-#include "dsp/filters/equalizer.hpp"
#include "dsp/signal.hpp"
using namespace bogaudio::dsp;
@@ -11,15 +9,6 @@ namespace bogaudio {
#define MIXER_PAN_SLEW_MS 10.0f
-template<int N>
-struct MixerExpanderMessage : ExpanderMessage {
- float preFader[N] {};
- float postFader[N] {};
- float postEQ[N] {};
- float returnA[2] {};
- float returnB[2] {};
-};
-
struct MixerChannel {
static const float maxDecibels;
static const float minDecibels;
@@ -54,60 +43,10 @@ struct MixerChannel {
}
void setSampleRate(float sampleRate);
+ void reset();
void next(float sample, bool solo, int c = 0); // outputs on members out, rms.
};
-struct MixerExpanderChannel {
- Equalizer _eq;
- Amplifier _sendAAmp;
- Amplifier _sendBAmp;
- bogaudio::dsp::SlewLimiter _sendASL;
- bogaudio::dsp::SlewLimiter _sendBSL;
-
- Param& _lowParam;
- Param& _midParam;
- Param& _highParam;
- Param& _sendAParam;
- Param& _sendBParam;
- Param& _preAParam;
- Param& _preBParam;
- Input& _sendAInput;
- Input& _sendBInput;
-
- float postEQ = 0.0f;
- float sendA = 0.0f;
- float sendB = 0.0f;
-
- MixerExpanderChannel(
- Param& low,
- Param& mid,
- Param& high,
- Param& sendA,
- Param& sendB,
- Param& preA,
- Param& preB,
- Input& cvA,
- Input& cvB,
- float sampleRate = 1000.0f
- )
- : _lowParam(low)
- , _midParam(mid)
- , _highParam(high)
- , _sendAParam(sendA)
- , _sendBParam(sendB)
- , _preAParam(preA)
- , _preBParam(preB)
- , _sendAInput(cvA)
- , _sendBInput(cvB)
- {
- setSampleRate(sampleRate);
- }
-
- void setSampleRate(float sampleRate);
- float knobToDb(Param& p);
- void next(float preFader, float postFader); // outputs on members postEQ, sendA, sendB
-};
-
struct MuteButton : ToggleButton {
MuteButton() {
addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/button_18px_0.svg")));
diff --git a/src/mixer_expander.cpp b/src/mixer_expander.cpp
@@ -0,0 +1,56 @@
+
+#include "mixer_expander.hpp"
+
+void MixerExpanderChannel::setSampleRate(float sampleRate) {
+ _sendASL.setParams(sampleRate, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
+ _sendBSL.setParams(sampleRate, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
+}
+
+float MixerExpanderChannel::knobToDb(Param& p) {
+ float v = clamp(p.getValue(), -1.0f, 1.0f);
+ if (v < 0.0f) {
+ return -v * Equalizer::cutDb;
+ }
+ return v * Equalizer::gainDb;
+}
+
+void MixerExpanderChannel::modulate() {
+ _eq.setParams(
+ APP->engine->getSampleRate(),
+ knobToDb(_lowParam),
+ knobToDb(_midParam),
+ knobToDb(_highParam)
+ );
+}
+
+void MixerExpanderChannel::next(float preFader, float postFader, bool sendAActive, bool sendBActive) {
+ postEQ = _eq.next(postFader);
+
+ if (sendAActive) {
+ float level = clamp(_sendAParam.getValue(), 0.0f, 1.0f);
+ if (_sendAInput.isConnected()) {
+ level *= clamp(_sendAInput.getVoltage() / 10.0f, 0.0f, 1.0f);
+ }
+ level = 1.0f - level;
+ level *= Amplifier::minDecibels;
+ _sendAAmp.setLevel(_sendASL.next(level));
+ sendA = _sendAAmp.next(_preAParam.getValue() > 0.5f ? preFader : postEQ);
+ }
+ else {
+ sendA = 0.0f;
+ }
+
+ if (sendBActive) {
+ float level = clamp(_sendBParam.getValue(), 0.0f, 1.0f);
+ if (_sendBInput.isConnected()) {
+ level *= clamp(_sendBInput.getVoltage() / 10.0f, 0.0f, 1.0f);
+ }
+ level = 1.0f - level;
+ level *= Amplifier::minDecibels;
+ _sendBAmp.setLevel(_sendBSL.next(level));
+ sendB = _sendBAmp.next(_preBParam.getValue() > 0.5f ? preFader : postEQ);
+ }
+ else {
+ sendB = 0.0f;
+ }
+}
diff --git a/src/mixer_expander.hpp b/src/mixer_expander.hpp
@@ -0,0 +1,71 @@
+#pragma once
+
+#include "mixer.hpp"
+#include "expanders.hpp"
+#include "dsp/filters/equalizer.hpp"
+
+namespace bogaudio {
+
+template<int N>
+struct MixerExpanderMessage : ExpanderMessage {
+ bool active[N] {};
+ float preFader[N] {};
+ float postFader[N] {};
+ float postEQ[N] {};
+ float returnA[2] {};
+ float returnB[2] {};
+};
+
+struct MixerExpanderChannel {
+ Equalizer _eq;
+ Amplifier _sendAAmp;
+ Amplifier _sendBAmp;
+ bogaudio::dsp::SlewLimiter _sendASL;
+ bogaudio::dsp::SlewLimiter _sendBSL;
+
+ Param& _lowParam;
+ Param& _midParam;
+ Param& _highParam;
+ Param& _sendAParam;
+ Param& _sendBParam;
+ Param& _preAParam;
+ Param& _preBParam;
+ Input& _sendAInput;
+ Input& _sendBInput;
+
+ float postEQ = 0.0f;
+ float sendA = 0.0f;
+ float sendB = 0.0f;
+
+ MixerExpanderChannel(
+ Param& low,
+ Param& mid,
+ Param& high,
+ Param& sendA,
+ Param& sendB,
+ Param& preA,
+ Param& preB,
+ Input& cvA,
+ Input& cvB,
+ float sampleRate = 1000.0f
+ )
+ : _lowParam(low)
+ , _midParam(mid)
+ , _highParam(high)
+ , _sendAParam(sendA)
+ , _sendBParam(sendB)
+ , _preAParam(preA)
+ , _preBParam(preB)
+ , _sendAInput(cvA)
+ , _sendBInput(cvB)
+ {
+ setSampleRate(sampleRate);
+ }
+
+ void setSampleRate(float sampleRate);
+ float knobToDb(Param& p);
+ void modulate();
+ void next(float preFader, float postFader, bool sendAActive, bool sendBActive); // outputs on members postEQ, sendA, sendB
+};
+
+} // namespace bogaudio