| 314 | } |
| 315 | |
| 316 | void process(const ProcessArgs& args) override { |
| 317 | |
| 318 | float_4 out[4][2] = {}, in[4][2] = {}; |
| 319 | |
| 320 | const int numPolyphonyEngines = std::max(inputs[LEFT_INPUT].getChannels(), inputs[RIGHT_INPUT].getChannels()); |
| 321 | |
| 322 | // slew mute to avoid clicks |
| 323 | const float muteGain = clickFilter.process(args.sampleTime, params[MUTE_PARAM].getValue() != MUTE_ON); |
| 324 | |
| 325 | if (inputs[LEFT_INPUT].isConnected() || inputs[RIGHT_INPUT].isConnected()) { |
| 326 | |
| 327 | const float switchGains = (params[IN_BOOST_PARAM].getValue() ? 2.0f : 1.0f) * (params[OUT_CUT_PARAM].getValue() ? 0.5f : 1.0f); |
| 328 | const float preVCAGain = switchGains * muteGain * std::pow(10, params[LEVEL_PARAM].getValue() / 20.0f); |
| 329 | |
| 330 | if (sliderUpdate.process()) { |
| 331 | updateEQsIfChanged(); |
| 332 | } |
| 333 | |
| 334 | for (int c = 0; c < numPolyphonyEngines; c += 4) { |
| 335 | |
| 336 | const float_4 postVCAGain = preVCAGain * clamp(inputs[LEVEL_INPUT].getNormalPolyVoltageSimd<float_4>(10.f, c) / 10.f, 0.f, 1.f); |
| 337 | |
| 338 | const float_4 panCV = clamp(params[PAN_CV_PARAM].getValue() * inputs[PAN_INPUT].getPolyVoltageSimd<float_4>(c) / 5.f, -1.f, +1.f); |
| 339 | const float_4 pan = clamp(params[PAN_PARAM].getValue() + panCV, -1.f, +1.f); |
| 340 | |
| 341 | // https://www.desmos.com/calculator/b0lisclikw |
| 342 | float_4 gainForSide[2] = {}; |
| 343 | switch (panningLaw) { |
| 344 | case LINEAR_6dB: { |
| 345 | gainForSide[0] = postVCAGain * (1.f - pan); |
| 346 | gainForSide[1] = postVCAGain * (1.f + pan); |
| 347 | break; |
| 348 | } |
| 349 | case EQUAL_POWER: { |
| 350 | gainForSide[0] = postVCAGain * simd::sqrt(1.f - pan); |
| 351 | gainForSide[1] = postVCAGain * simd::sqrt(1.f + pan); |
| 352 | break; |
| 353 | } |
| 354 | case LINEAR_CLIPPED: { |
| 355 | gainForSide[0] = simd::ifelse(pan < 0, postVCAGain, postVCAGain * (1.f - pan)); |
| 356 | gainForSide[1] = simd::ifelse(pan > 0, postVCAGain, postVCAGain * (1.f + pan)); |
| 357 | break; |
| 358 | } |
| 359 | } |
| 360 | |
| 361 | in[c / 4][LEFT] = inputs[LEFT_INPUT].getPolyVoltageSimd<float_4>(c); |
| 362 | in[c / 4][RIGHT] = inputs[RIGHT_INPUT].getNormalPolyVoltageSimd<float_4>(in[c / 4][LEFT], c); |
| 363 | |
| 364 | for (int side = 0; side < 2; ++side) { |
| 365 | |
| 366 | float_4 outForSide = in[c / 4][side]; |
| 367 | |
| 368 | outForSide = eqLow[c / 4][side].process(outForSide); |
| 369 | outForSide = eqMid[c / 4][side].process(outForSide); |
| 370 | outForSide = eqHigh[c / 4][side].process(outForSide); |
| 371 | outForSide = applyHighpass ? highpass[c / 4][side].process(outForSide) : outForSide; |
| 372 | outForSide = applyHighshelf ? highshelf[c / 4][side].process(outForSide) : outForSide; |
| 373 | outForSide = outForSide * gainForSide[side]; |
nothing calls this directly
no test coverage detected