You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.5KB

  1. #include "plugin.hpp"
  2. using simd::float_4;
  3. struct CVMix : Module {
  4. enum ParamId {
  5. ENUMS(LEVEL_PARAMS, 3),
  6. PARAMS_LEN
  7. };
  8. enum InputId {
  9. ENUMS(CV_INPUTS, 3),
  10. INPUTS_LEN
  11. };
  12. enum OutputId {
  13. MIX_OUTPUT,
  14. OUTPUTS_LEN
  15. };
  16. enum LightId {
  17. LIGHTS_LEN
  18. };
  19. CVMix() {
  20. config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN);
  21. for (int i = 0; i < 3; i++)
  22. configParam(LEVEL_PARAMS + i, -1.f, 1.f, 0.f, string::f("Level %d", i + 1), "%", 0, 100);
  23. for (int i = 0; i < 3; i++)
  24. configInput(CV_INPUTS + i, string::f("CV %d", i + 1));
  25. configOutput(MIX_OUTPUT, "Mix");
  26. }
  27. void process(const ProcessArgs& args) override {
  28. if (!outputs[MIX_OUTPUT].isConnected())
  29. return;
  30. // Get number of channels
  31. int channels = 1;
  32. for (int i = 0; i < 3; i++)
  33. channels = std::max(channels, inputs[CV_INPUTS + i].getChannels());
  34. for (int c = 0; c < channels; c += 4) {
  35. // Sum CV inputs
  36. float_4 mix = 0.f;
  37. for (int i = 0; i < 3; i++) {
  38. // Normalize inputs to 10V
  39. float_4 cv = inputs[CV_INPUTS + i].getNormalPolyVoltageSimd<float_4>(10.f, c);
  40. // Apply gain
  41. cv *= params[LEVEL_PARAMS + i].getValue();
  42. mix += cv;
  43. }
  44. // Set mix output
  45. outputs[MIX_OUTPUT].setVoltageSimd(mix, c);
  46. }
  47. outputs[MIX_OUTPUT].setChannels(channels);
  48. }
  49. };
  50. struct CVMixWidget : ModuleWidget {
  51. CVMixWidget(CVMix* module) {
  52. setModule(module);
  53. setPanel(createPanel(asset::plugin(pluginInstance, "res/CVMix.svg")));
  54. addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0)));
  55. addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  56. addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  57. addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  58. addParam(createParamCentered<RoundBlackKnob>(mm2px(Vec(7.62, 24.723)), module, CVMix::LEVEL_PARAMS + 0));
  59. addParam(createParamCentered<RoundBlackKnob>(mm2px(Vec(7.62, 41.327)), module, CVMix::LEVEL_PARAMS + 1));
  60. addParam(createParamCentered<RoundBlackKnob>(mm2px(Vec(7.62, 57.922)), module, CVMix::LEVEL_PARAMS + 2));
  61. addInput(createInputCentered<PJ301MPort>(mm2px(Vec(7.62, 76.539)), module, CVMix::CV_INPUTS + 0));
  62. addInput(createInputCentered<PJ301MPort>(mm2px(Vec(7.62, 86.699)), module, CVMix::CV_INPUTS + 1));
  63. addInput(createInputCentered<PJ301MPort>(mm2px(Vec(7.62, 96.859)), module, CVMix::CV_INPUTS + 2));
  64. addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(7.62, 113.115)), module, CVMix::MIX_OUTPUT));
  65. }
  66. };
  67. Model* modelCVMix = createModel<CVMix, CVMixWidget>("CVMix");