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.

554 lines
17KB

  1. #include "Klee.hpp"
  2. namespace rack_plugin_TheXOR {
  3. void Klee::on_loaded()
  4. {
  5. #ifdef DIGITAL_EXT
  6. connected = 0;
  7. #endif
  8. load();
  9. }
  10. void Klee::step()
  11. {
  12. float deltaTime = 1.0 / engineGetSampleRate();
  13. if(loadTrigger.process(params[LOAD_PARAM].value + inputs[LOAD_INPUT].value))
  14. {
  15. load();
  16. }
  17. int clk = clockTrigger.process(inputs[EXT_CLOCK_INPUT].value + params[STEP_PARAM].value); // 1=rise, -1=fall
  18. if(clk == 1)
  19. {
  20. sr_rotate();
  21. update_bus();
  22. populate_outputs();
  23. }
  24. if(clk != 0)
  25. {
  26. populate_gate(clk);
  27. }
  28. check_triggers(deltaTime);
  29. showValues();
  30. #ifdef DIGITAL_EXT
  31. bool dig_connected = false;
  32. #ifdef LAUNCHPAD
  33. if(drv->Connected())
  34. dig_connected = true;
  35. drv->ProcessLaunchpad();
  36. #endif
  37. #if defined(OSCTEST_MODULE)
  38. if(oscDrv->Connected())
  39. dig_connected = true;
  40. oscDrv->ProcessOSC();
  41. #endif
  42. connected = dig_connected ? 1.0 : 0.0;
  43. #endif
  44. }
  45. void Klee::load()
  46. {
  47. for(int k = 0; k < 16; k++)
  48. {
  49. shiftRegister.P[k] = isSwitchOn(LOAD_BUS + k);
  50. }
  51. }
  52. void Klee::update_bus()
  53. {
  54. bool bus1 = bus_active[0];
  55. for(int k = 0; k < 3; k++)
  56. bus_active[k] = false;
  57. for(int k = 0; k < 16; k++)
  58. {
  59. if(shiftRegister.P[k])
  60. {
  61. bus_active[getValue3(k)] = true;
  62. }
  63. }
  64. if(isSwitchOn(BUS2_MODE))
  65. bus_active[1] = bus_active[0] && bus_active[2];
  66. else
  67. bus_active[1] &= !(bus_active[0] || bus_active[2]); //BUS 2: NOR 0 , 3
  68. //bus1 load
  69. if(isSwitchOn(BUS1_LOAD) && !bus1 && bus_active[0])
  70. load();
  71. }
  72. int Klee::getValue3(int k)
  73. {
  74. int v = roundf(params[GROUPBUS + k].value);
  75. return 2-v;
  76. }
  77. bool Klee::isSwitchOn(int ptr)
  78. {
  79. return params[ptr].value > 0.1;
  80. }
  81. void Klee::check_triggers(float deltaTime)
  82. {
  83. for(int k = 0; k < 3; k++)
  84. {
  85. if(outputs[TRIG_OUT + k].value > 0.5 && !triggers[k].process(deltaTime))
  86. {
  87. outputs[TRIG_OUT + k].value = LVL_OFF;
  88. }
  89. }
  90. }
  91. void Klee::populate_gate(int clk)
  92. {
  93. for(int k = 0; k < 3; k++)
  94. {
  95. // gate
  96. if(clk == 1) // rise
  97. {
  98. outputs[GATE_OUT + k].value = bus_active[k] ? LVL_ON : LVL_OFF;
  99. } else // fall
  100. {
  101. if(!bus_active[k] || !isSwitchOn(BUS_MERGE + k))
  102. outputs[GATE_OUT + k].value = LVL_OFF;
  103. }
  104. }
  105. }
  106. void Klee::populate_outputs()
  107. {
  108. for(int k = 0; k < 3; k++)
  109. {
  110. if(bus_active[k])
  111. {
  112. outputs[TRIG_OUT + k].value = LVL_ON;
  113. triggers[k].trigger(pulseTime);
  114. }
  115. }
  116. float a = 0, b = 0;
  117. float mult = params[RANGE].value + inputs[RANGE_IN].value;
  118. for(int k = 0; k < 8; k++)
  119. {
  120. if(shiftRegister.A[k])
  121. a += params[PITCH_KNOB + k].value*mult;
  122. if(shiftRegister.B[k])
  123. b += params[PITCH_KNOB + k + 8].value*mult;
  124. }
  125. outputs[CV_A].value = a;
  126. outputs[CV_B].value = b;
  127. outputs[CV_AB].value = a + b;
  128. outputs[CV_A__B].value = a - b;
  129. }
  130. void Klee::showValues()
  131. {
  132. for(int k = 0; k < 16; k++)
  133. {
  134. lights[LED_PITCH + k].value = shiftRegister.P[k] ? 1.0 : 0;
  135. }
  136. for(int k = 0; k < 3; k++)
  137. {
  138. lights[LED_BUS + k].value = outputs[GATE_OUT + k].value;
  139. }
  140. }
  141. void Klee::sr_rotate()
  142. {
  143. if(!isSwitchOn(X28_X16)) // mode 1 x 16
  144. {
  145. int fl = shiftRegister.P[15];
  146. for(int k = 15; k > 0; k--)
  147. {
  148. shiftRegister.P[k] = shiftRegister.P[k - 1];
  149. }
  150. if(isSwitchOn(RND_PAT))
  151. shiftRegister.P[0] = chance();
  152. else
  153. shiftRegister.P[0] = fl;
  154. } else
  155. {
  156. int fla = shiftRegister.A[7];
  157. int flb = shiftRegister.B[7];
  158. for(int k = 7; k > 0; k--)
  159. {
  160. shiftRegister.A[k] = shiftRegister.A[k - 1];
  161. shiftRegister.B[k] = shiftRegister.B[k - 1];
  162. }
  163. if(isSwitchOn(RND_PAT))
  164. shiftRegister.A[0] = chance();
  165. else
  166. shiftRegister.A[0] = fla;
  167. shiftRegister.B[0] = isSwitchOn(B_INV) ? !flb : flb;
  168. }
  169. }
  170. bool Klee::chance()
  171. {
  172. return rand() <= (params[RND_THRESHOLD].value + inputs[RND_THRES_IN].value) * RAND_MAX;
  173. }
  174. KleeWidget::KleeWidget(Klee *module) : SequencerWidget(module)
  175. {
  176. float nkk_offs = 2.3;
  177. #ifdef OSCTEST_MODULE
  178. char name[60];
  179. #endif
  180. #ifdef LAUNCHPAD
  181. int numLaunchpads = module->drv->GetNumLaunchpads();
  182. #ifdef DEBUG
  183. info("%i launchpad found", numLaunchpads);
  184. #endif
  185. #endif
  186. box.size = Vec(48 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  187. SVGPanel *panel = new SVGPanel();
  188. panel->box.size = box.size;
  189. panel->setBackground(SVG::load(assetPlugin(plugin, "res/modules/KleeModule.svg")));
  190. addChild(panel);
  191. addChild(Widget::create<ScrewBlack>(Vec(RACK_GRID_WIDTH, 0)));
  192. addChild(Widget::create<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  193. addChild(Widget::create<ScrewBlack>(Vec(RACK_GRID_WIDTH, box.size.y - RACK_GRID_WIDTH)));
  194. addChild(Widget::create<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, box.size.y - RACK_GRID_WIDTH)));
  195. const float switch_dstx = 22.203 - 11.229;
  196. for(int k = 0; k < 8; k++)
  197. {
  198. // Load switches
  199. ParamWidget *pwdg = ParamWidget::create<NKK2>(Vec(mm2px(k*switch_dstx+11.229), yncscape(114.071+ nkk_offs,7.336)), module, Klee::LOAD_BUS + k, 0.0, 1.0, 0.0);
  200. addParam(pwdg);
  201. #ifdef LAUNCHPAD
  202. if(numLaunchpads > 1)
  203. {
  204. LaunchpadSwitch *sw = new LaunchpadSwitch(0, 0, ILaunchpadPro::RC2Key(1, k), LaunchpadLed::Color(11), LaunchpadLed::Color(5));
  205. module->drv->Add(sw, pwdg);
  206. } else
  207. {
  208. LaunchpadSwitch *sw = new LaunchpadSwitch(0, ILaunchpadPro::RC2Key(2, k), LaunchpadLed::Color(11), LaunchpadLed::Color(5));
  209. module->drv->Add(sw, pwdg);
  210. }
  211. #endif
  212. #ifdef OSCTEST_MODULE
  213. sprintf(name, "/Load%i", k+1);
  214. oscControl *oc = new oscControl(name);
  215. module->oscDrv->Add(oc, pwdg);
  216. #endif
  217. pwdg = ParamWidget::create<NKK2>(Vec(mm2px(k*switch_dstx + 118.914), yncscape(114.071+nkk_offs, 7.336)), module, Klee::LOAD_BUS + k + 8, 0.0, 1.0, 0.0);
  218. addParam(pwdg);
  219. #ifdef LAUNCHPAD
  220. if(numLaunchpads > 1)
  221. {
  222. LaunchpadSwitch *sw = new LaunchpadSwitch(1, 0, ILaunchpadPro::RC2Key(1, k), LaunchpadLed::Color(19), LaunchpadLed::Color(17));
  223. module->drv->Add(sw, pwdg);
  224. } else
  225. {
  226. LaunchpadSwitch *sw = new LaunchpadSwitch(0, ILaunchpadPro::RC2Key(3, k), LaunchpadLed::Color(19), LaunchpadLed::Color(17));
  227. module->drv->Add(sw, pwdg);
  228. }
  229. #endif
  230. #ifdef OSCTEST_MODULE
  231. sprintf(name, "/Load%i", k + 9);
  232. oc = new oscControl(name);
  233. module->oscDrv->Add(oc, pwdg);
  234. #endif
  235. // BUS switches
  236. pwdg = ParamWidget::create<NKK2>(Vec(mm2px(k*switch_dstx + 11.229), yncscape(4.502 + nkk_offs, 7.336)), module, Klee::GROUPBUS + k, 0.0, 2.0, 2.0);
  237. addParam(pwdg);
  238. #ifdef LAUNCHPAD
  239. if(numLaunchpads > 1)
  240. {
  241. LaunchpadRadio *radio = new LaunchpadRadio(0, 0, ILaunchpadPro::RC2Key(5, k), 3, LaunchpadLed::Color(7), LaunchpadLed::Color(5));
  242. module->drv->Add(radio, pwdg);
  243. } else
  244. {
  245. LaunchpadThree *three = new LaunchpadThree(0, ILaunchpadPro::RC2Key(6, k), LaunchpadLed::Color(7), LaunchpadLed::Color(6), LaunchpadLed::Color(5));
  246. module->drv->Add(three, pwdg);
  247. }
  248. #endif
  249. #ifdef OSCTEST_MODULE
  250. sprintf(name, "/Bus%i", k + 1);
  251. oc = new oscControl(name);
  252. module->oscDrv->Add(oc, pwdg);
  253. #endif
  254. pwdg = ParamWidget::create<NKK2>(Vec(mm2px(k*switch_dstx + 118.914), yncscape(4.502 + nkk_offs, 7.336)), module, Klee::GROUPBUS + k + 8, 0.0, 2.0, 2.0);
  255. addParam(pwdg);
  256. #ifdef LAUNCHPAD
  257. if(numLaunchpads > 1)
  258. {
  259. LaunchpadRadio *radio = new LaunchpadRadio(1, 0, ILaunchpadPro::RC2Key(5, k), 3, LaunchpadLed::Color(17), LaunchpadLed::Color(19));
  260. module->drv->Add(radio, pwdg);
  261. } else
  262. {
  263. LaunchpadThree *three = new LaunchpadThree(0, ILaunchpadPro::RC2Key(7, k), LaunchpadLed::Color(17), LaunchpadLed::Color(18), LaunchpadLed::Color(19));
  264. module->drv->Add(three, pwdg);
  265. }
  266. #endif
  267. #ifdef OSCTEST_MODULE
  268. sprintf(name, "/Bus%i", k + 9);
  269. oc = new oscControl(name);
  270. module->oscDrv->Add(oc, pwdg);
  271. #endif
  272. }
  273. // trig/gate out
  274. float dist_v = 60.582 - 76.986;
  275. for(int k = 0; k < 3; k++)
  276. {
  277. ParamWidget *pwdg = ParamWidget::create<NKK2>(Vec(mm2px(184.360), yncscape(76.986 + nkk_offs +k*dist_v, 7.336)), module, Klee::BUS_MERGE + k, 0.0, 1.0, 0.0);
  278. addParam(pwdg);
  279. #ifdef LAUNCHPAD
  280. LaunchpadSwitch *sw = new LaunchpadSwitch(ALL_LAUNCHPADS, launchpadDriver::ALL_PAGES, ILaunchpadPro::RC2Key(8, 4 + k), LaunchpadLed::Color(11), LaunchpadLed::Color(52));
  281. module->drv->Add(sw, pwdg);
  282. #endif
  283. #ifdef OSCTEST_MODULE
  284. sprintf(name, "/Merge%i", k + 1);
  285. oscControl *oc = new oscControl(name);
  286. module->oscDrv->Add(oc, pwdg);
  287. #endif
  288. ModuleLightWidget *plight = ModuleLightWidget::create<LargeLight<BlueLight>>(Vec(mm2px(205.425), yncscape(78.065 + k*dist_v, 5.179)), module, Klee::LED_BUS + k);
  289. addChild(plight);
  290. #ifdef OSCTEST_MODULE
  291. sprintf(name, "/BusLed%i", k + 1);
  292. oc = new oscControl(name);
  293. module->oscDrv->Add(oc, plight);
  294. #endif
  295. addOutput(Port::create<PJ301BLUPort>(Vec(mm2px(213.360), yncscape(76.986+k*dist_v, 8.255)), Port::OUTPUT, module, Klee::TRIG_OUT + k));
  296. addOutput(Port::create<PJ301WPort>(Vec(mm2px(230.822), yncscape(76.986+k*dist_v, 8.255)), Port::OUTPUT, module, Klee::GATE_OUT + k));
  297. }
  298. ParamWidget *pwdg = ParamWidget::create<CKSSFix>(Vec(mm2px(172.113), yncscape(61.520, 5.460)), module, Klee::BUS2_MODE, 0.0, 1.0, 0.0);
  299. addParam(pwdg);
  300. #ifdef LAUNCHPAD
  301. LaunchpadSwitch *sw = new LaunchpadSwitch(ALL_LAUNCHPADS, launchpadDriver::ALL_PAGES, LaunchpadKey::STOP_CLIP, LaunchpadLed::Color(55), LaunchpadLed::Color(57));
  302. module->drv->Add(sw, pwdg);
  303. #endif
  304. #ifdef OSCTEST_MODULE
  305. sprintf(name, "/Bus2Mode");
  306. oscControl *oc = new oscControl(name);
  307. module->oscDrv->Add(oc, pwdg);
  308. #endif
  309. //load
  310. pwdg = ParamWidget::create<BefacoPushBig>(Vec(mm2px(25.360), yncscape(76.686,8.999)), module, Klee::LOAD_PARAM, 0.0, 1.0, 0.0);
  311. addParam(pwdg);
  312. #ifdef LAUNCHPAD
  313. LaunchpadMomentary *mom = new LaunchpadMomentary(ALL_LAUNCHPADS, launchpadDriver::ALL_PAGES, LaunchpadKey::RECORD, LaunchpadLed::Color(1), LaunchpadLed::Color(43));
  314. module->drv->Add(mom, pwdg);
  315. #endif
  316. #ifdef OSCTEST_MODULE
  317. sprintf(name, "/Load");
  318. oc = new oscControl(name);
  319. module->oscDrv->Add(oc, pwdg);
  320. #endif
  321. addInput(Port::create<PJ301BPort>(Vec(mm2px(9.218), yncscape(77.058, 8.255)), Port::INPUT, module, Klee::LOAD_INPUT));
  322. pwdg = ParamWidget::create<NKK2>(Vec(mm2px(25.627), yncscape(91.395 + nkk_offs, 7.336)), module, Klee::BUS1_LOAD, 0.0, 1.0, 0.0);
  323. addParam(pwdg);
  324. #ifdef LAUNCHPAD
  325. sw = new LaunchpadSwitch(ALL_LAUNCHPADS, launchpadDriver::ALL_PAGES, LaunchpadKey::RECORD_ARM, LaunchpadLed::Color(31), LaunchpadLed::Color(33));
  326. module->drv->Add(sw, pwdg);
  327. #endif
  328. #ifdef OSCTEST_MODULE
  329. sprintf(name, "/Bus1Load");
  330. oc = new oscControl(name);
  331. module->oscDrv->Add(oc, pwdg);
  332. #endif
  333. //step
  334. pwdg = ParamWidget::create<BefacoPushBig>(Vec(mm2px(25.360), yncscape(24.737, 8.999)), module, Klee::STEP_PARAM, 0.0, 1.0, 0.0);
  335. addParam(pwdg);
  336. #ifdef LAUNCHPAD
  337. mom = new LaunchpadMomentary(ALL_LAUNCHPADS, launchpadDriver::ALL_PAGES, LaunchpadKey::CLICK, LaunchpadLed::Color(1), LaunchpadLed::Color(9));
  338. module->drv->Add(mom, pwdg);
  339. #endif
  340. #ifdef OSCTEST_MODULE
  341. sprintf(name, "/Step");
  342. oc = new oscControl(name);
  343. module->oscDrv->Add(oc, pwdg);
  344. #endif
  345. addInput(Port::create<PJ301RPort>(Vec(mm2px(9.218), yncscape(25.109, 8.255)), Port::INPUT, module, Klee::EXT_CLOCK_INPUT));
  346. // CV Out
  347. addOutput(Port::create<PJ301GPort>(Vec(mm2px(213.360), yncscape(113.612, 8.255)), Port::OUTPUT, module, Klee::CV_A));
  348. addOutput(Port::create<PJ301GPort>(Vec(mm2px(230.822), yncscape(113.612, 8.255)), Port::OUTPUT, module, Klee::CV_B));
  349. addOutput(Port::create<PJ301GPort>(Vec(mm2px(213.360), yncscape(97.207, 8.255)), Port::OUTPUT, module, Klee::CV_A__B));
  350. addOutput(Port::create<PJ301GPort>(Vec(mm2px(230.822), yncscape(97.207, 8.255)), Port::OUTPUT, module, Klee::CV_AB));
  351. // mode
  352. pwdg = ParamWidget::create<NKK2>(Vec(mm2px(68.915), yncscape(60.582 + nkk_offs, 7.336)), module, Klee::X28_X16, 0.0, 1.0, 0.0);
  353. addParam(pwdg); // 2x8 1x16
  354. #ifdef LAUNCHPAD
  355. sw = new LaunchpadSwitch(ALL_LAUNCHPADS, launchpadDriver::ALL_PAGES, LaunchpadKey::TRACK_SELECT, LaunchpadLed::Color(1), LaunchpadLed::Color(62));
  356. module->drv->Add(sw, pwdg);
  357. #endif
  358. #ifdef OSCTEST_MODULE
  359. sprintf(name, "/Mode");
  360. oc = new oscControl(name);
  361. module->oscDrv->Add(oc, pwdg);
  362. #endif
  363. pwdg = ParamWidget::create<NKK2>(Vec(mm2px(97.459), yncscape(60.582 + nkk_offs, 7.336)), module, Klee::RND_PAT, 0.0, 1.0, 0.0);
  364. addParam(pwdg); // rnd/pattern
  365. #ifdef LAUNCHPAD
  366. sw = new LaunchpadSwitch(ALL_LAUNCHPADS, launchpadDriver::ALL_PAGES, LaunchpadKey::MUTE, LaunchpadLed::Color(1), LaunchpadLed::Color(62));
  367. module->drv->Add(sw, pwdg);
  368. #endif
  369. #ifdef OSCTEST_MODULE
  370. sprintf(name, "/Random");
  371. oc = new oscControl(name);
  372. module->oscDrv->Add(oc, pwdg);
  373. #endif
  374. pwdg = ParamWidget::create<NKK2>(Vec(mm2px(126.004), yncscape(60.582 + nkk_offs, 7.336)), module, Klee::B_INV, 0.0, 1.0, 0.0);
  375. addParam(pwdg); // norm /B inverted
  376. #ifdef LAUNCHPAD
  377. sw = new LaunchpadSwitch(ALL_LAUNCHPADS, launchpadDriver::ALL_PAGES, LaunchpadKey::SOLO, LaunchpadLed::Color(1), LaunchpadLed::Color(62));
  378. module->drv->Add(sw, pwdg);
  379. #endif
  380. #ifdef OSCTEST_MODULE
  381. sprintf(name, "/Invert");
  382. oc = new oscControl(name);
  383. module->oscDrv->Add(oc, pwdg);
  384. #endif
  385. // CV Range
  386. pwdg = ParamWidget::create<Davies1900hFixBlackKnob>(Vec(mm2px(212.725), yncscape(24.474,9.525)), module, Klee::RANGE, 0.0001, 5.0, 1.0);
  387. addParam(pwdg);
  388. #ifdef OSCTEST_MODULE
  389. sprintf(name, "/Range");
  390. oc = new oscControl(name);
  391. module->oscDrv->Add(oc, pwdg);
  392. #endif
  393. addInput(Port::create<PJ301BPort>(Vec(mm2px(230.822), yncscape(25.109, 8.255)), Port::INPUT, module, Klee::RANGE_IN));
  394. // RND Threshold
  395. pwdg = ParamWidget::create<Davies1900hFixBlackKnob>(Vec(mm2px(212.725), yncscape(9.228, 9.525)), module, Klee::RND_THRESHOLD, 0.0, 1.0, 0.0);
  396. addParam(pwdg); // rnd threshold
  397. #ifdef OSCTEST_MODULE
  398. sprintf(name, "/RndTH");
  399. oc = new oscControl(name);
  400. module->oscDrv->Add(oc, pwdg);
  401. #endif
  402. addInput(Port::create<PJ301BPort>(Vec(mm2px(230.822), yncscape(9.863, 8.255)), Port::INPUT, module, Klee::RND_THRES_IN));
  403. // pitch Knobs + leds
  404. float pot_x[8] = {39.440, 45.104, 60.976, 83.912, 109.368, 132.304, 148.175, 153.840};
  405. float led_x[8] = {51.727, 56.481, 69.800, 89.046, 110.408, 129.655, 142.974, 147.727};
  406. float pot_y_sup[8] = {66.558, 79.131, 89.222, 94.823, 94.823, 89.222, 79.131, 66.558};
  407. float pot_y_inf[8] = {52.426, 39.814, 29.751, 24.152, 24.152, 29.751, 39.814, 52.426};
  408. float led_y_sup[8] = {67.079, 76.624, 84.279, 88.527, 88.527, 84.279, 76.624, 67.079};
  409. float led_y_inf[8] = {58.245, 48.700, 41.045, 36.797, 36.797, 41.045, 48.700, 58.245};
  410. for(int k = 0; k < 8; k++)
  411. {
  412. pwdg = ParamWidget::create<Davies1900hFixRedKnob>(Vec(mm2px(pot_x[k]), yncscape(pot_y_sup[k], 9.525)), module, Klee::PITCH_KNOB + k, 0.0, 1.0, 0.125);
  413. addParam(pwdg);
  414. #ifdef OSCTEST_MODULE
  415. sprintf(name, "/Knob%i", k+1);
  416. oc = new oscControl(name);
  417. module->oscDrv->Add(oc, pwdg);
  418. #endif
  419. ModuleLightWidget *plight = ModuleLightWidget::create<MediumLight<RedLight>>(Vec(mm2px(led_x[k]), yncscape(led_y_sup[k], 3.176)), module, Klee::LED_PITCH + k);
  420. addChild(plight);
  421. #ifdef LAUNCHPAD
  422. if(numLaunchpads > 1)
  423. {
  424. LaunchpadLight *ld1 = new LaunchpadLight(0, launchpadDriver::ALL_PAGES, ILaunchpadPro::RC2Key(0, k), LaunchpadLed::Off(), LaunchpadLed::Color(5));
  425. module->drv->Add(ld1, plight);
  426. } else
  427. {
  428. LaunchpadLight *ld1 = new LaunchpadLight(launchpadDriver::ALL_PAGES, ILaunchpadPro::RC2Key(0, k), LaunchpadLed::Off(), LaunchpadLed::Color(5));
  429. module->drv->Add(ld1, plight);
  430. }
  431. #endif
  432. #ifdef OSCTEST_MODULE
  433. sprintf(name, "/Ledbpm_integer");
  434. oc = new oscControl(name);
  435. module->oscDrv->Add(oc, plight);
  436. #endif
  437. pwdg = ParamWidget::create<Davies1900hFixWhiteKnob>(Vec(mm2px(pot_x[7-k]), yncscape(pot_y_inf[k], 9.525)), module, Klee::PITCH_KNOB + 8 + k, 0.0, 1.0, 0.125);
  438. addParam(pwdg);
  439. #ifdef OSCTEST_MODULE
  440. sprintf(name, "/Knob%i", k + 9);
  441. oc = new oscControl(name);
  442. module->oscDrv->Add(oc, pwdg);
  443. #endif
  444. plight = ModuleLightWidget::create<MediumLight<WhiteLight>>(Vec(mm2px(led_x[7-k]), yncscape(led_y_inf[k], 3.176)), module, Klee::LED_PITCH + k + 8);
  445. addChild(plight);
  446. #ifdef LAUNCHPAD
  447. if(numLaunchpads > 1)
  448. {
  449. LaunchpadLight *ld1 = new LaunchpadLight(1, launchpadDriver::ALL_PAGES, ILaunchpadPro::RC2Key(0, k), LaunchpadLed::Off(), LaunchpadLed::Color(21));
  450. module->drv->Add(ld1, plight);
  451. } else
  452. {
  453. LaunchpadLight *ld1 = new LaunchpadLight(launchpadDriver::ALL_PAGES, ILaunchpadPro::RC2Key(1, k), LaunchpadLed::Off(), LaunchpadLed::Color(21));
  454. module->drv->Add(ld1, plight);
  455. }
  456. #endif
  457. #ifdef OSCTEST_MODULE
  458. sprintf(name, "/Led%i", k + 9);
  459. oc = new oscControl(name);
  460. module->oscDrv->Add(oc, plight);
  461. #endif
  462. }
  463. #ifdef DIGITAL_EXT
  464. addChild(new DigitalLed(mm2px(104.205), yncscape(115.806, 3.867), &module->connected));
  465. #endif
  466. }
  467. Menu *KleeWidget::addContextMenu(Menu *menu)
  468. {
  469. menu->addChild(new SeqMenuItem<KleeWidget>("Range -> 1V", this, SET_RANGE_1V));
  470. menu->addChild(new SeqMenuItem<KleeWidget>("Randomize Pitch", this, RANDOMIZE_PITCH));
  471. menu->addChild(new SeqMenuItem<KleeWidget>("Randomize Bus", this, RANDOMIZE_BUS));
  472. menu->addChild(new SeqMenuItem<KleeWidget>("Randomize Load", this, RANDOMIZE_LOAD));
  473. return menu;
  474. }
  475. void KleeWidget::onMenu(int action)
  476. {
  477. switch(action)
  478. {
  479. case RANDOMIZE_BUS: std_randomize(Klee::GROUPBUS, Klee::GROUPBUS + 16); break;
  480. case RANDOMIZE_PITCH: std_randomize(Klee::PITCH_KNOB, Klee::PITCH_KNOB + 16); break;
  481. case RANDOMIZE_LOAD: std_randomize(Klee::LOAD_BUS, Klee::LOAD_BUS + 16); break;
  482. case SET_RANGE_1V:
  483. {
  484. int index = getParamIndex(Klee::RANGE);
  485. if(index >= 0)
  486. params[index]->setValue(1.0);
  487. }
  488. break;
  489. }
  490. }
  491. } // namespace rack_plugin_TheXOR
  492. using namespace rack_plugin_TheXOR;
  493. RACK_PLUGIN_MODEL_INIT(TheXOR, Klee) {
  494. return Model::create<Klee, KleeWidget>("TheXOR", "Klee", "Klee Sequencer", SEQUENCER_TAG);
  495. }