| 78 | } |
| 79 | |
| 80 | void process(const ProcessArgs& args) override { |
| 81 | bool advanceStep = false; |
| 82 | |
| 83 | const bool isHoldOutRequired = outputs[OUT_OUTPUT].isConnected() && inputs[IN_INPUT].isConnected(); |
| 84 | const bool isClockOutRequired = outputs[CLOCK_OUTPUT].isConnected(); |
| 85 | const bool isTriggOutRequired = outputs[TRIGG_OUTPUT].isConnected(); |
| 86 | |
| 87 | if (params[INT_EXT_PARAM].getValue() == CLOCK_EXTERNAL) { |
| 88 | // if external mode, the SYNC/EXT. CLOCK input acts as a clock |
| 89 | advanceStep = clock.process(rescale(inputs[SYNC_INPUT].getVoltage(), 0.1f, 2.f, 0.f, 1.f)); |
| 90 | } |
| 91 | else { |
| 92 | // if internal mode, the SYNC/EXT. CLOCK input acts as oscillator sync, resetting the phase |
| 93 | if (clock.process(rescale(inputs[SYNC_INPUT].getVoltage(), 0.1f, 2.f, 0.f, 1.f))) { |
| 94 | advanceStep = true; |
| 95 | stepPhase = 0.f; |
| 96 | halfPhase = false; |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | if (holdDetector.process(rescale(inputs[HOLD_INPUT].getVoltage(), 0.1f, 2.f, 0.f, 1.f))) { |
| 101 | float oldHeldValue = heldValue; |
| 102 | heldValue = inputs[IN_INPUT].getVoltage(); |
| 103 | holdMinBlep.insertDiscontinuity(0, heldValue - oldHeldValue); |
| 104 | } |
| 105 | |
| 106 | for (int i = 0; i < numSteps; i++) { |
| 107 | stepStates[i] = (StepState) params[STEP_PARAM + i].getValue(); |
| 108 | } |
| 109 | int numActiveSteps = 0; |
| 110 | numEffectiveSteps = 8; |
| 111 | for (int i = 0; i < numSteps; i++) { |
| 112 | numActiveSteps += (stepStates[i] == STATE_ON); |
| 113 | if (stepStates[i] == STATE_RESET) { |
| 114 | numEffectiveSteps = i; |
| 115 | break; |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | const float pitch = 16.f * params[RATE_PARAM].getValue() + params[FINE_PARAM].getValue() + inputs[VOCT_INPUT].getVoltage(); |
| 120 | const float minDialFrequency = 1.0f; |
| 121 | const float frequency = minDialFrequency * simd::pow(2.f, pitch); |
| 122 | |
| 123 | const float oldPhase = stepPhase; |
| 124 | float deltaPhase = clamp(args.sampleTime * frequency, 1e-6f, 0.5f); |
| 125 | stepPhase += deltaPhase; |
| 126 | |
| 127 | if (!halfPhase && stepPhase >= 0.5) { |
| 128 | |
| 129 | float crossing = -(stepPhase - 0.5) / deltaPhase; |
| 130 | if (isClockOutRequired) { |
| 131 | squareMinBlep.insertDiscontinuity(crossing, -2.f); |
| 132 | } |
| 133 | if (isTriggOutRequired && stepStates[currentStep] == STATE_ON) { |
| 134 | triggMinBlep.insertDiscontinuity(crossing, -2.f); |
| 135 | } |
| 136 | |
| 137 | halfPhase = true; |