The below (truncated) patch technically works as a possible fix but is unfortunately too slow. At least confirms the 1-sample delay theory. Does anyone know a more efficient way to detect if the current module is self patched (i.e. without iterating over all cables)?
I also initially tried a hook in draw doing something like APP->scene->rack->getCompleteCablesOnPort(this->getInput(Muxlicer::GATE_MODE_INPUT)); etc but that seems wrong (e.g. it wouldn’t work in headless).
diff --git a/src/Muxlicer.cpp b/src/Muxlicer.cpp
index 8f24a0e..2ae079e 100644
--- a/src/Muxlicer.cpp
+++ b/src/Muxlicer.cpp
// there is an option to stop output clock when play stops
const bool playStateMask = !outputClockFollowsPlayMode || (playState != STATE_STOPPED);
// NOTE: outputClockOut can also be read by expanders
@@ -611,6 +611,31 @@ struct Muxlicer : Module {
}
}
+ bool isCOMIOSelfPatchedToGateInput() {
+ // if either is not connected then we're not self patched
+ if (!inputs[GATE_MODE_INPUT].isConnected() || !outputs[COM_OUTPUT].isConnected()) {
+ return false;
+ }
+
+ // loop over all cables
+ for (int64_t cableId : APP->engine->getCableIds()) {
+
+ // if _this_ muxlicer has a self patching cable
+ const bool selfPatchedCurrentModule = (APP->engine->getCable(cableId)->inputModule->id == this->id &&
+ APP->engine->getCable(cableId)->outputModule->id == this->id);
+ if (selfPatchedCurrentModule) {
+ // and that self patch is COM IO -> Gate Input
+ const bool comIOToGateInput = (APP->engine->getCable(cableId)->inputId == GATE_MODE_INPUT &&
+ APP->engine->getCable(cableId)->outputId == COM_OUTPUT);
+
+ if (comIOToGateInput) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
// determines how many gates to yield per step
int getGateMode() {
@@ -618,9 +643,12 @@ struct Muxlicer : Module {
int gate;
if (inputs[GATE_MODE_INPUT].isConnected()) {
+
+ float cvIn = isCOMIOSelfPatchedToGateInput() ? outputs[COM_OUTPUT].getVoltage() : inputs[GATE_MODE_INPUT].getVoltage();
+
// with gate acting as attenuator, hardware reacts in 1V increments,
// where x V -> (x + 1) V yields (x - 1) gates in that time
- float gateCV = clamp(inputs[GATE_MODE_INPUT].getVoltage(), 0.f, 10.f);
+ float gateCV = clamp(cvIn, 0.f, 10.f);
float knobAttenuation = rescale(params[GATE_MODE_PARAM].getValue(), -1.f, 8.f, 0.f, 1.f);
gate = int (floor(gateCV * knobAttenuation)) - 1;
