ComputerscareGolyPenerator.cpp (7917B)
1 #include "Computerscare.hpp" 2 3 #include "dtpulse.hpp" 4 #include "golyFunctions.hpp" 5 6 struct ComputerscareGolyPenerator; 7 8 9 /* 10 knob1: number of channels output 1-16 11 knob2: algorithm 12 knob3: param 1 13 */ 14 const std::string GolyPeneratorAvailableAlgorithmsArr[5] = {"Linear", "Sigmoid", "Hump", "Sinusoid", "Pseudo-Random"}; 15 16 17 //template <const std::string& options> 18 struct GolyAlgoParamQuantity : ParamQuantity { 19 std::string getDisplayValueString() override { 20 int val = getValue(); 21 return GolyPeneratorAvailableAlgorithmsArr[val]; 22 } 23 }; 24 25 struct ComputerscareGolyPenerator : ComputerscareMenuParamModule { 26 int counter = 0; 27 int numChannels = 16; 28 ComputerscareSVGPanel* panelRef; 29 Goly goly; 30 float currentValues[16] = {0.f}; 31 std::vector<std::string> availableAlgorithms; 32 33 enum ParamIds { 34 ALGORITHM, 35 IN_OFFSET, 36 IN_SCALE, 37 OUT_SCALE, 38 OUT_OFFSET, 39 POLY_CHANNELS, 40 COLOR, 41 NUM_PARAMS 42 }; 43 enum InputIds { 44 CHANNEL_INPUT, 45 NUM_INPUTS 46 }; 47 enum OutputIds { 48 POLY_OUTPUT, 49 NUM_OUTPUTS 50 }; 51 enum LightIds { 52 NUM_LIGHTS 53 }; 54 55 56 ComputerscareGolyPenerator() { 57 58 config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 59 60 configParam<GolyAlgoParamQuantity>(ALGORITHM , 0.f, 4.f, 0.f, "Algorithm"); 61 configParam(IN_OFFSET, -1.f, 1.f, 0.f, "Channel Center"); 62 63 configParam(IN_SCALE, -2.f, 2.f, 1.f, "Channel Spread"); 64 65 configParam(OUT_SCALE, -20.f, 20.f, 10.f, "Output Scale"); 66 configParam(OUT_OFFSET, -10.f, 10.f, 0.f, "Output Offset"); 67 configParam<AutoParamQuantity>(POLY_CHANNELS, 1.f, 16.f, 16.f, "Poly Channels"); 68 configMenuParam(COLOR, 0.f, 9.f, 0.f, "Display Color", 2); 69 70 getParamQuantity(POLY_CHANNELS)->randomizeEnabled = false; 71 getParamQuantity(POLY_CHANNELS)->resetEnabled = false; 72 73 configOutput(POLY_OUTPUT, "Main"); 74 75 availableAlgorithms.push_back("Linear"); 76 availableAlgorithms.push_back("Sigmoid"); 77 availableAlgorithms.push_back("Hump"); 78 availableAlgorithms.push_back("Sinusoid"); 79 availableAlgorithms.push_back("Pseudo-Random"); 80 81 82 goly = Goly(); 83 84 } 85 void updateCurrents() { 86 std::vector<float> golyParams = {params[IN_OFFSET].getValue(), params[IN_SCALE].getValue(), params[OUT_SCALE].getValue(), params[OUT_OFFSET].getValue()}; 87 goly.invoke((int) std::floor(params[ALGORITHM].getValue()), golyParams, params[POLY_CHANNELS].getValue()); 88 } 89 void setAlgorithm(int algoVal) { 90 params[ALGORITHM].setValue(algoVal); 91 } 92 void checkPoly() override { 93 int knobSetting = params[POLY_CHANNELS].getValue(); 94 polyChannels = knobSetting == 0 ? 16 : knobSetting; 95 outputs[POLY_OUTPUT].setChannels(polyChannels); 96 } 97 void process(const ProcessArgs &args) override { 98 ComputerscarePolyModule::checkCounter(); 99 counter++; 100 if (counter > 13) { 101 counter = 0; 102 updateCurrents(); 103 //numChannels=(int) (std::floor(params[POLY_CHANNELS].getValue())); 104 } 105 106 107 //outputs[POLY_OUTPUT].setChannels(numChannels); 108 for (int i = 0; i < polyChannels; i++) { 109 outputs[POLY_OUTPUT].setVoltage(goly.currentValues[i], i); 110 } 111 } 112 113 }; 114 struct setAlgoItem : MenuItem 115 { 116 ComputerscareGolyPenerator *penerator; 117 int mySetVal; 118 setAlgoItem(int setVal) 119 { 120 mySetVal = setVal; 121 } 122 123 void onAction(const event::Action &e) override 124 { 125 penerator->setAlgorithm(mySetVal); 126 } 127 void step() override { 128 rightText = CHECKMARK(penerator->params[ComputerscareGolyPenerator::ALGORITHM].getValue() == mySetVal); 129 MenuItem::step(); 130 } 131 }; 132 133 struct AlgorithmChildMenu : MenuItem { 134 ComputerscareGolyPenerator *penerator; 135 136 Menu *createChildMenu() override { 137 Menu *menu = new Menu; 138 menu->addChild(construct<MenuLabel>(&MenuLabel::text, "Select an Algorithm... NOW")); 139 140 for (unsigned int i = 0; i < penerator->availableAlgorithms.size(); i++) { 141 setAlgoItem *menuItem = new setAlgoItem(i); 142 //ParamSettingItem *menuItem = new ParamSettingItem(i,ComputerscareGolyPenerator::ALGORITHM); 143 144 menuItem->text = penerator->availableAlgorithms[i]; 145 menuItem->penerator = penerator; 146 menu->addChild(menuItem); 147 } 148 149 return menu; 150 } 151 152 }; 153 struct PeneratorDisplay : TransparentWidget { 154 ComputerscareGolyPenerator *module; 155 156 PeneratorDisplay() { 157 158 } 159 void drawLayer(const BGPanel::DrawArgs& args, int layer) override { 160 if (layer == 1) { 161 float valsToDraw[16] = {1.f}; 162 int ch = 16; 163 float colorArg; 164 165 if (module) { 166 ch = module->polyChannels; 167 colorArg = module->params[ComputerscareGolyPenerator::COLOR].getValue(); 168 for (int i = 0; i < ch; i++) { 169 valsToDraw[i] = module->goly.currentValues[i]; 170 } 171 } 172 else { 173 for (int i = 0; i < ch; i++) { 174 valsToDraw[i] = random::uniform() * 10; 175 } 176 colorArg = random::uniform() * 2; 177 } 178 DrawHelper draw = DrawHelper(args.vg); 179 Points pts = Points(); 180 181 nvgTranslate(args.vg, box.size.x / 2, box.size.y / 2 + 5); 182 pts.linear(ch, Vec(0, -box.size.y / 2), Vec(0, 150)); 183 std::vector<Vec> polyVals; 184 std::vector<NVGcolor> colors; 185 std::vector<Vec> thicknesses; 186 187 for (int i = 0; i < 16; i++) { 188 polyVals.push_back(Vec(valsToDraw[i] * 2, 0.f)); 189 colors.push_back(draw.sincolor(colorArg, {1, 1, 0})); 190 191 thicknesses.push_back(Vec(160 / (1 + ch), 0)); 192 } 193 draw.drawLines(pts.get(), polyVals, colors, thicknesses); 194 } 195 } 196 }; 197 struct ComputerscareGolyPeneratorWidget : ModuleWidget { 198 ComputerscareGolyPeneratorWidget(ComputerscareGolyPenerator *module) { 199 200 setModule(module); 201 box.size = Vec(4 * 15, 380); 202 { 203 ComputerscareSVGPanel *panel = new ComputerscareSVGPanel(); 204 panel->box.size = box.size; 205 panel->setBackground(APP->window->loadSvg(asset::plugin(pluginInstance, "res/ComputerscareGolyPeneratorPanel.svg"))); 206 addChild(panel); 207 } 208 209 PeneratorDisplay *display = new PeneratorDisplay(); 210 display->module = module; 211 display->box.pos = Vec(0, 120); 212 display->box.size = Vec(box.size.x, 400); 213 addChild(display); 214 215 addLabeledKnob<ScrambleSnapKnob>("Algo", 4, 324, module, ComputerscareGolyPenerator::ALGORITHM, 0, 0, true); 216 addLabeledKnob<SmoothKnob>("center", 28, 80, module, ComputerscareGolyPenerator::IN_OFFSET, 0, 0); 217 addLabeledKnob<SmallKnob>("spread", 5, 86, module, ComputerscareGolyPenerator::IN_SCALE, 0, 0); 218 addLabeledKnob<SmallKnob>("scale", 33, 290, module, ComputerscareGolyPenerator::OUT_SCALE, 0, 0); 219 addLabeledKnob<SmoothKnob>("offset", 2, 284, module, ComputerscareGolyPenerator::OUT_OFFSET, 0, 0); 220 221 channelWidget = new PolyOutputChannelsWidget(Vec(28, 309), module, ComputerscareGolyPenerator::POLY_CHANNELS); 222 addChild(channelWidget); 223 224 addOutput(createOutput<InPort>(Vec(28, 329), module, ComputerscareGolyPenerator::POLY_OUTPUT)); 225 226 } 227 void appendContextMenu(Menu* menu) override { 228 ComputerscareGolyPenerator* penerator = dynamic_cast<ComputerscareGolyPenerator*>(this->module); 229 230 MenuParam* colorParam = new MenuParam(penerator->paramQuantities[ComputerscareGolyPenerator::COLOR], 2); 231 menu->addChild(colorParam); 232 233 menu->addChild(new MenuSeparator); 234 235 AlgorithmChildMenu *algoMenu = new AlgorithmChildMenu(); 236 algoMenu->text = "Algorithm"; 237 algoMenu->rightText = RIGHT_ARROW; 238 algoMenu->penerator = penerator; 239 menu->addChild(algoMenu); 240 } 241 242 template <typename BASE> 243 void addLabeledKnob(std::string label, int x, int y, ComputerscareGolyPenerator *module, int paramIndex, float labelDx, float labelDy, bool snap = false) { 244 245 smallLetterDisplay = new SmallLetterDisplay(); 246 smallLetterDisplay->box.size = Vec(5, 10); 247 smallLetterDisplay->fontSize = 14; 248 smallLetterDisplay->value = label; 249 smallLetterDisplay->textAlign = 1; 250 251 if (snap) { 252 addParam(createParam<BASE>(Vec(x, y), module, paramIndex)); 253 } 254 else { 255 addParam(createParam<BASE>(Vec(x, y), module, paramIndex)); 256 257 } 258 smallLetterDisplay->box.pos = Vec(x + labelDx, y - 12 + labelDy); 259 260 261 //addChild(smallLetterDisplay); 262 263 } 264 PolyOutputChannelsWidget* channelWidget; 265 266 SmallLetterDisplay* smallLetterDisplay; 267 }; 268 269 Model *modelComputerscareGolyPenerator = createModel<ComputerscareGolyPenerator, ComputerscareGolyPeneratorWidget>("computerscare-goly-penerator");