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.

416 lines
19KB

  1. #include "Amalgam.hpp"
  2. Amalgam::Amalgam() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
  3. amalgamType = 0;
  4. __zeros = _mm_set1_ps(0.f);
  5. __fives = _mm_set1_ps(5.f);
  6. __halfs = _mm_set1_ps(0.5f);
  7. __x = __zeros;
  8. __y = __zeros;
  9. __z = __zeros;
  10. __xyAnd = __zeros;
  11. __xyXor = __zeros;
  12. xGain = 0.f;
  13. yGain = 0.f;
  14. float newSampleRate = engineGetSampleRate();
  15. vecAmalgam.setSampleRate(newSampleRate);
  16. xyAndDCFilter.setSampleRate(newSampleRate);
  17. xyXorDCFilter.setSampleRate(newSampleRate);
  18. zOutDCFilter.setSampleRate(newSampleRate);
  19. zPls1DCFilter.setSampleRate(newSampleRate);
  20. zPls2DCFilter.setSampleRate(newSampleRate);
  21. zAndDCFilter.setSampleRate(newSampleRate);
  22. zXorDCFilter.setSampleRate(newSampleRate);
  23. xyAndDCFilter.setCutoffFreq(1.f);
  24. xyXorDCFilter.setCutoffFreq(1.f);
  25. zOutDCFilter.setCutoffFreq(1.f);
  26. zPls1DCFilter.setCutoffFreq(1.f);
  27. zPls2DCFilter.setCutoffFreq(1.f);
  28. zAndDCFilter.setCutoffFreq(1.f);
  29. zXorDCFilter.setCutoffFreq(1.f);
  30. }
  31. void Amalgam::step() {
  32. amalgamType = inputs[TYPE_CV1_INPUT].value * params[TYPE_CV1_PARAM].value;
  33. amalgamType += inputs[TYPE_CV2_INPUT].value * params[TYPE_CV2_PARAM].value;
  34. amalgamType = rescale(amalgamType, 0.f, 10.f, 0.f, (float)VecAmalgam::NUM_MODES);
  35. amalgamType += params[TYPE_PARAM].value;
  36. iAmalgamType = (int)clamp(amalgamType, 0.f, (float)VecAmalgam::NUM_MODES - 1);
  37. vecAmalgam.setMode(iAmalgamType);
  38. paramA = params[A_PARAM].value;
  39. paramA += inputs[PARAM_A_CV1_INPUT].value * 0.1f * params[PARAM_A_CV1_PARAM].value;
  40. paramA += inputs[PARAM_A_CV2_INPUT].value * 0.1f * params[PARAM_A_CV2_PARAM].value;
  41. paramA = clamp(paramA, 0.f, 1.f);
  42. paramB = params[B_PARAM].value;
  43. paramB += inputs[PARAM_B_CV1_INPUT].value * 0.1f * params[PARAM_B_CV1_PARAM].value;
  44. paramB += inputs[PARAM_B_CV2_INPUT].value * 0.1f * params[PARAM_B_CV2_PARAM].value;
  45. paramB = clamp(paramB, 0.f, 1.f);
  46. dcCoupleButtonState = params[DC_COUPLE_PARAM].value > 0.5f ? true : false;
  47. if(dcCoupleButtonState && !prevDcCoupleButtonState) {
  48. dcCoupled = dcCoupled ? false : true;
  49. }
  50. prevDcCoupleButtonState = dcCoupleButtonState;
  51. lights[DC_COUPLE_LIGHT].value = dcCoupled ? 10.f : 0.f;
  52. xyAndDCFilter.setBypass(dcCoupled);
  53. xyXorDCFilter.setBypass(dcCoupled);
  54. zOutDCFilter.setBypass(dcCoupled);
  55. zPls1DCFilter.setBypass(dcCoupled);
  56. zPls2DCFilter.setBypass(dcCoupled);
  57. xIn[0] = inputs[X_LEFT_INPUT].value;
  58. xIn[1] = inputs[X_RIGHT_INPUT].value;
  59. yIn[0] = inputs[Y_LEFT_INPUT].value;
  60. yIn[1] = inputs[Y_RIGHT_INPUT].value;
  61. // Normal route left and right inputs if used in mono
  62. if(inputs[X_LEFT_INPUT].active && !inputs[X_RIGHT_INPUT].active) {
  63. xIn[1] = xIn[0];
  64. }
  65. else if(!inputs[X_LEFT_INPUT].active && inputs[X_RIGHT_INPUT].active) {
  66. xIn[0] = xIn[1];
  67. }
  68. if(inputs[Y_LEFT_INPUT].active && !inputs[Y_RIGHT_INPUT].active) {
  69. yIn[1] = yIn[0];
  70. }
  71. else if(!inputs[Y_LEFT_INPUT].active && inputs[Y_RIGHT_INPUT].active) {
  72. yIn[0] = yIn[1];
  73. }
  74. xGain = inputs[X_GAIN_CV_INPUT].value * params[X_GAIN_CV_PARAM].value * 0.4f;
  75. xGain += params[X_GAIN].value;
  76. xGain = clamp(xGain, 0.f, 4.f);
  77. yGain = inputs[Y_GAIN_CV_INPUT].value * params[Y_GAIN_CV_PARAM].value * 0.4;
  78. yGain += params[Y_GAIN].value;
  79. yGain = clamp(yGain, 0.f, 4.f);
  80. __x = _mm_set_ps(xIn[0], xIn[0], xIn[1], xIn[1]);
  81. __y = _mm_set_ps(yIn[0], yIn[0], yIn[1], yIn[1]);
  82. __x = _mm_mul_ps(__x, _mm_set1_ps(0.15f));
  83. __y = _mm_mul_ps(__y, _mm_set1_ps(0.15f));
  84. __x = _mm_mul_ps(vecDriveSignal(__x, _mm_set1_ps(xGain)), _mm_set1_ps(1.333333f));
  85. __y = _mm_mul_ps(vecDriveSignal(__y, _mm_set1_ps(yGain)), _mm_set1_ps(1.333333f));
  86. // AND and XOR
  87. __xyAnd = _mm_switch_ps(__zeros, __fives, _mm_and_ps(_mm_cmpgt_ps(__x, __zeros), _mm_cmpgt_ps(__y, __zeros)));
  88. __xyXor = _mm_switch_ps(__zeros, __fives, _mm_xor_ps(_mm_cmpgt_ps(__x, __zeros), _mm_cmpgt_ps(__y, __zeros)));
  89. __xyAnd = xyAndDCFilter.process(__xyAnd);
  90. __xyXor = xyXorDCFilter.process(__xyXor);
  91. __z = vecAmalgam.process(__x, __y, paramA, paramB);
  92. __zPls1Mask = _mm_cmpgt_ps(__z, __zeros);
  93. __zPls1 = _mm_and_ps(__fives, _mm_and_ps(_mm_cmpgt_ps(__z, __zeros), _mm_cmple_ps(__z, __halfs)));
  94. __zPls2 = _mm_and_ps(__fives, _mm_or_ps(_mm_and_ps(_mm_cmpgt_ps(__z, __zeros), _mm_cmple_ps(__z, _mm_set1_ps(0.25f))),
  95. _mm_and_ps(_mm_cmpgt_ps(__z, __halfs), _mm_cmple_ps(__z, _mm_set1_ps(0.99f)))));
  96. __zPls1 = zPls1DCFilter.process(__zPls1);
  97. __zPls2 = zPls2DCFilter.process(__zPls2);
  98. _mm_storeu_ps(zOut, __z);
  99. _mm_storeu_ps(zPls1, __zPls1);
  100. _mm_storeu_ps(zPls2, __zPls2);
  101. _mm_storeu_ps(andOut, __xyAnd);
  102. _mm_storeu_ps(xorOut, __xyXor);
  103. zAnd = (zOut[0] > 0.f) & (zOut[2] > 0.f) ? 5.f : 0.f;
  104. zXor = (zOut[0] > 0.f) ^ (zOut[2] > 0.f) ? 5.f : 0.f;
  105. zAndDCFilter.input = zAnd;
  106. zXorDCFilter.input = zXor;
  107. zAndDCFilter.process();
  108. zXorDCFilter.process();
  109. zAnd = dcCoupled ? zAnd : zAndDCFilter.output;
  110. zXor = dcCoupled ? zXor : zXorDCFilter.output;
  111. __z = zOutDCFilter.process(__z);
  112. _mm_storeu_ps(zOut, __z);
  113. outputs[X_Y_LEFT_AND_OUTPUT].value = andOut[2];
  114. outputs[X_Y_RIGHT_AND_OUTPUT].value = andOut[0];
  115. outputs[X_Y_LEFT_XOR_OUTPUT].value = xorOut[2];
  116. outputs[X_Y_RIGHT_XOR_OUTPUT].value = xorOut[0];
  117. outputs[Z_LEFT_OUTPUT].value = tanhDriveSignal(zOut[0], 0.66f) * 5.5f;
  118. outputs[Z_RIGHT_OUTPUT].value = tanhDriveSignal(zOut[2], 0.66f) * 5.5f;
  119. outputs[Z_AND_OUTPUT].value = zAnd;
  120. outputs[Z_XOR_OUTPUT].value = zXor;
  121. outputs[Z_LEFT_PULSE_1_OUTPUT].value = zPls1[2];
  122. outputs[Z_RIGHT_PULSE_1_OUTPUT].value = zPls1[0];
  123. outputs[Z_LEFT_PULSE_2_OUTPUT].value = zPls2[2];
  124. outputs[Z_RIGHT_PULSE_2_OUTPUT].value = zPls2[0];
  125. }
  126. void Amalgam::onSampleRateChange() {
  127. float newSampleRate = engineGetSampleRate();
  128. vecAmalgam.setSampleRate(newSampleRate);
  129. xyAndDCFilter.setSampleRate(newSampleRate);
  130. xyXorDCFilter.setSampleRate(newSampleRate);
  131. zOutDCFilter.setSampleRate(newSampleRate);
  132. zPls1DCFilter.setSampleRate(newSampleRate);
  133. zPls2DCFilter.setSampleRate(newSampleRate);
  134. }
  135. json_t* Amalgam::toJson() {
  136. json_t *rootJ = json_object();
  137. int dcCoupledI = dcCoupled ? 1 : 0;
  138. json_object_set_new(rootJ, "panelStyle", json_integer(panelStyle));
  139. json_object_set_new(rootJ, "dcCoupled", json_integer(dcCoupledI));
  140. return rootJ;
  141. }
  142. void Amalgam::fromJson(json_t *rootJ) {
  143. json_t *panelStyleJ = json_object_get(rootJ, "panelStyle");
  144. json_t *dcCoupledJ = json_object_get(rootJ, "dcCoupled");
  145. panelStyle = json_integer_value(panelStyleJ);
  146. dcCoupled = json_integer_value(dcCoupledJ) ? true : false;
  147. }
  148. ////////////////////////////////////////////////////////////////////////////////////////////////////
  149. void AmalgamPanelStyleItem::onAction(EventAction &e) {
  150. module->panelStyle = panelStyle;
  151. }
  152. void AmalgamPanelStyleItem::step() {
  153. rightText = (module->panelStyle == panelStyle) ? "✔" : "";
  154. MenuItem::step();
  155. }
  156. ////////////////////////////////////////////////////////////////////////////////////////////////////
  157. AmalgamWidget::AmalgamWidget(Amalgam* module) : ModuleWidget(module) {
  158. {
  159. DynamicPanelWidget *panel = new DynamicPanelWidget();
  160. panel->addPanel(SVG::load(assetPlugin(plugin, "res/AmalgamPanelDark.svg")));
  161. panel->addPanel(SVG::load(assetPlugin(plugin, "res/AmalgamPanelLight.svg")));
  162. box.size = panel->box.size;
  163. panel->mode = &module->panelStyle;
  164. addChild(panel);
  165. }
  166. addChild(Widget::create<ScrewBlack>(Vec(RACK_GRID_WIDTH, 0)));
  167. addChild(Widget::create<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  168. addChild(Widget::create<ScrewBlack>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  169. addChild(Widget::create<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  170. // Make jacks
  171. addInput(Port::create<PJ301MDarkSmall>(xLeftInputPos, Port::INPUT, module, Amalgam::X_LEFT_INPUT));
  172. addInput(Port::create<PJ301MDarkSmall>(xRightInputPos, Port::INPUT, module, Amalgam::X_RIGHT_INPUT));
  173. addInput(Port::create<PJ301MDarkSmall>(yLeftInputPos, Port::INPUT, module, Amalgam::Y_LEFT_INPUT));
  174. addInput(Port::create<PJ301MDarkSmall>(yRightInputPos, Port::INPUT, module, Amalgam::Y_RIGHT_INPUT));
  175. addInput(Port::create<PJ301MDarkSmall>(xDriveCVInputPos, Port::INPUT, module, Amalgam::X_GAIN_CV_INPUT));
  176. addInput(Port::create<PJ301MDarkSmall>(yDriveCVInputPos, Port::INPUT, module, Amalgam::Y_GAIN_CV_INPUT));
  177. //addInput(Port::create<PJ301MDarkSmall>(modeCVInputPos, Port::INPUT, module, Amalgam::MODE_CV_INPUT));
  178. addInput(Port::create<PJ301MDarkSmall>(typeCV1InputPos, Port::INPUT, module, Amalgam::TYPE_CV1_INPUT));
  179. addInput(Port::create<PJ301MDarkSmall>(typeCV2InputPos, Port::INPUT, module, Amalgam::TYPE_CV2_INPUT));
  180. addInput(Port::create<PJ301MDarkSmall>(paramACV1InputPos, Port::INPUT, module, Amalgam::PARAM_A_CV1_INPUT));
  181. addInput(Port::create<PJ301MDarkSmall>(paramACV2InputPos, Port::INPUT, module, Amalgam::PARAM_A_CV2_INPUT));
  182. addInput(Port::create<PJ301MDarkSmall>(paramBCV1InputPos, Port::INPUT, module, Amalgam::PARAM_B_CV1_INPUT));
  183. addInput(Port::create<PJ301MDarkSmall>(paramBCV2InputPos, Port::INPUT, module, Amalgam::PARAM_B_CV2_INPUT));
  184. addOutput(Port::create<PJ301MDarkSmallOut>(leftANDOutputPos, Port::OUTPUT, module, Amalgam::X_Y_LEFT_AND_OUTPUT));
  185. addOutput(Port::create<PJ301MDarkSmallOut>(leftXOROutputPos, Port::OUTPUT, module, Amalgam::X_Y_LEFT_XOR_OUTPUT));
  186. addOutput(Port::create<PJ301MDarkSmallOut>(rightANDOutputPos, Port::OUTPUT, module, Amalgam::X_Y_RIGHT_AND_OUTPUT));
  187. addOutput(Port::create<PJ301MDarkSmallOut>(rightXOROutputPos, Port::OUTPUT, module, Amalgam::X_Y_RIGHT_XOR_OUTPUT));
  188. addOutput(Port::create<PJ301MDarkSmallOut>(zLeftOutputPos, Port::OUTPUT, module, Amalgam::Z_LEFT_OUTPUT));
  189. addOutput(Port::create<PJ301MDarkSmallOut>(zRightOutputPos, Port::OUTPUT, module, Amalgam::Z_RIGHT_OUTPUT));
  190. addOutput(Port::create<PJ301MDarkSmallOut>(zANDOutputPos, Port::OUTPUT, module, Amalgam::Z_AND_OUTPUT));
  191. addOutput(Port::create<PJ301MDarkSmallOut>(zXOROutputPos, Port::OUTPUT, module, Amalgam::Z_XOR_OUTPUT));
  192. addOutput(Port::create<PJ301MDarkSmallOut>(zLeftPulseOutputPos, Port::OUTPUT, module, Amalgam::Z_LEFT_PULSE_1_OUTPUT));
  193. addOutput(Port::create<PJ301MDarkSmallOut>(zRightPulseOutputPos, Port::OUTPUT, module, Amalgam::Z_RIGHT_PULSE_1_OUTPUT));
  194. addOutput(Port::create<PJ301MDarkSmallOut>(zLeftPulse2OutputPos, Port::OUTPUT, module, Amalgam::Z_LEFT_PULSE_2_OUTPUT));
  195. addOutput(Port::create<PJ301MDarkSmallOut>(zRightPulse2OutputPos, Port::OUTPUT, module, Amalgam::Z_RIGHT_PULSE_2_OUTPUT));
  196. // Knobs
  197. addParam(ParamWidget::create<RoganSmallWhite>(xDriveKnobPos, module, Amalgam::X_GAIN, 0.f, 4.f, 1.f));
  198. addParam(ParamWidget::create<RoganSmallWhite>(yDriveKnobPos, module, Amalgam::Y_GAIN, 0.f, 4.f, 1.f));
  199. //addParam(ParamWidget::create<RoganMedSmallWhite>(modeKnobPos, module, Amalgam::MODE_PARAM, 0.f, 1.f, 0.f));
  200. addParam(ParamWidget::create<DynRoganMedGreen>(paramAKnobPos, module, Amalgam::A_PARAM, 0.0f, 1.f, 0.f));
  201. addParam(ParamWidget::create<DynRoganMedBlue>(paramBKnobPos, module, Amalgam::B_PARAM, 0.0f, 1.f, 0.f));
  202. addParam(ParamWidget::create<RoganMedWhite>(typeKnobPos, module, Amalgam::TYPE_PARAM, 0.0f, VecAmalgam::NUM_MODES - 0.9f, 0.f));
  203. addParam(ParamWidget::create<RoganSmallWhite>(modeCV1KnobPos, module, Amalgam::TYPE_CV1_PARAM, -1.0f, 1.f, 0.0f));
  204. addParam(ParamWidget::create<RoganSmallWhite>(modeCV2KnobPos, module, Amalgam::TYPE_CV2_PARAM, -1.0f, 1.f, 0.0f));
  205. addParam(ParamWidget::create<RoganSmallWhite>(xDriveCVKnobPos, module, Amalgam::X_GAIN_CV_PARAM, -1.0f, 1.f, 0.0f));
  206. addParam(ParamWidget::create<RoganSmallWhite>(yDriveCVKnobPos, module, Amalgam::Y_GAIN_CV_PARAM, -1.0f, 1.f, 0.0f));
  207. addParam(ParamWidget::create<RoganSmallGreen>(paramACV1KnobPos, module, Amalgam::PARAM_A_CV1_PARAM, -1.0f, 1.f, 0.0f));
  208. addParam(ParamWidget::create<RoganSmallGreen>(paramACV2KnobPos, module, Amalgam::PARAM_A_CV2_PARAM, -1.0f, 1.f, 0.0f));
  209. addParam(ParamWidget::create<RoganSmallBlue>(paramBCV1KnobPos, module, Amalgam::PARAM_B_CV1_PARAM, -1.0f, 1.f, 0.0f));
  210. addParam(ParamWidget::create<RoganSmallBlue>(paramBCV2KnobPos, module, Amalgam::PARAM_B_CV2_PARAM, -1.0f, 1.f, 0.0f));
  211. {
  212. DynamicText* modeBackText = new DynamicText;
  213. modeBackText->size = 13;
  214. modeBackText->box.pos = Vec(75, 95.5);
  215. modeBackText->box.size = Vec(82, 14);
  216. modeBackText->visibility = nullptr;
  217. modeBackText->viewMode = ACTIVE_LOW_VIEW;
  218. modeBackText->horzAlignment = NVG_ALIGN_CENTER;
  219. modeBackText->setFont(DynamicText::FontMode::FONT_MODE_7SEG);
  220. modeBackText->text = make_shared<std::string>("~~~~~~~~");
  221. modeBackText->customColor = nvgRGB(0x4F,0x00,0x00);
  222. addChild(modeBackText);
  223. }
  224. {
  225. DynamicFrameText* modeText = new DynamicFrameText;
  226. modeText->size = 13;
  227. modeText->box.pos = Vec(75, 95.5);
  228. modeText->box.size = Vec(82, 14);
  229. modeText->itemHandle = &module->iAmalgamType;
  230. modeText->visibility = nullptr;
  231. modeText->viewMode = ACTIVE_LOW_VIEW;
  232. modeText->horzAlignment = NVG_ALIGN_CENTER;
  233. modeText->colorHandle = &module->textColor;
  234. modeText->setFont(DynamicText::FontMode::FONT_MODE_7SEG);
  235. for(auto i = 0; i < VecAmalgam::NUM_MODES; ++i) {
  236. modeText->addItem(module->modeNames[i]);
  237. }
  238. addChild(modeText);
  239. }
  240. {
  241. DynamicFrameText* modeBlurText = new DynamicFrameText;
  242. modeBlurText->size = 13;
  243. modeBlurText->blur = 8.f;
  244. modeBlurText->box.pos = Vec(75, 95.5);
  245. modeBlurText->box.size = Vec(82, 14);
  246. modeBlurText->itemHandle = &module->iAmalgamType;
  247. modeBlurText->visibility = nullptr;
  248. modeBlurText->viewMode = ACTIVE_LOW_VIEW;
  249. modeBlurText->horzAlignment = NVG_ALIGN_CENTER;
  250. modeBlurText->customColor = nvgRGB(0xFF, 0x7F, 0x7F);
  251. modeBlurText->setFont(DynamicText::FontMode::FONT_MODE_7SEG);
  252. for(auto i = 0; i < VecAmalgam::NUM_MODES; ++i) {
  253. modeBlurText->addItem(module->modeNames[i]);
  254. }
  255. addChild(modeBlurText);
  256. }
  257. {
  258. DynamicText* paramABackText = new DynamicText;
  259. paramABackText->size = 12;
  260. paramABackText->box.pos = Vec(75, 177);
  261. paramABackText->box.size = Vec(82, 14);
  262. paramABackText->visibility = nullptr;
  263. paramABackText->viewMode = ACTIVE_LOW_VIEW;
  264. paramABackText->horzAlignment = NVG_ALIGN_CENTER;
  265. paramABackText->setFont(DynamicText::FontMode::FONT_MODE_7SEG);
  266. paramABackText->text = make_shared<std::string>("~~~~~~~~");
  267. paramABackText->customColor = nvgRGB(0x4F,0x00,0x00);
  268. addChild(paramABackText);
  269. }
  270. {
  271. DynamicFrameText* paramAText = new DynamicFrameText;
  272. paramAText->size = 12;
  273. paramAText->box.pos = Vec(75, 177);
  274. paramAText->box.size = Vec(82, 14);
  275. paramAText->itemHandle = &module->iAmalgamType;
  276. paramAText->visibility = nullptr;
  277. paramAText->viewMode = ACTIVE_LOW_VIEW;
  278. paramAText->horzAlignment = NVG_ALIGN_CENTER;
  279. paramAText->colorHandle = &module->textColor;
  280. paramAText->setFont(DynamicText::FontMode::FONT_MODE_7SEG);
  281. for(auto i = 0; i < VecAmalgam::NUM_MODES; ++i) {
  282. paramAText->addItem(module->paramANames[i]);
  283. }
  284. addChild(paramAText);
  285. }
  286. {
  287. DynamicFrameText* paramABlurText = new DynamicFrameText;
  288. paramABlurText->size = 12;
  289. paramABlurText->blur = 8.f;
  290. paramABlurText->box.pos = Vec(75, 177);
  291. paramABlurText->box.size = Vec(82, 14);
  292. paramABlurText->itemHandle = &module->iAmalgamType;
  293. paramABlurText->visibility = nullptr;
  294. paramABlurText->viewMode = ACTIVE_LOW_VIEW;
  295. paramABlurText->horzAlignment = NVG_ALIGN_CENTER;
  296. paramABlurText->customColor = nvgRGB(0xFF, 0x7F, 0x7F);
  297. paramABlurText->setFont(DynamicText::FontMode::FONT_MODE_7SEG);
  298. for(auto i = 0; i < VecAmalgam::NUM_MODES; ++i) {
  299. paramABlurText->addItem(module->paramANames[i]);
  300. }
  301. addChild(paramABlurText);
  302. }
  303. {
  304. DynamicText* paramBBackText = new DynamicText;
  305. paramBBackText->size = 12;
  306. paramBBackText->box.pos = Vec(75, 249);
  307. paramBBackText->box.size = Vec(82, 14);
  308. paramBBackText->visibility = nullptr;
  309. paramBBackText->viewMode = ACTIVE_LOW_VIEW;
  310. paramBBackText->horzAlignment = NVG_ALIGN_CENTER;
  311. paramBBackText->setFont(DynamicText::FontMode::FONT_MODE_7SEG);
  312. paramBBackText->text = make_shared<std::string>("~~~~~~~~");
  313. paramBBackText->customColor = nvgRGB(0x4F,0x00,0x00);
  314. addChild(paramBBackText);
  315. }
  316. {
  317. DynamicFrameText* paramBText = new DynamicFrameText;
  318. paramBText->size = 12;
  319. paramBText->box.pos = Vec(75, 249);
  320. paramBText->box.size = Vec(82, 14);
  321. paramBText->itemHandle = &module->iAmalgamType;
  322. paramBText->visibility = nullptr;
  323. paramBText->viewMode = ACTIVE_LOW_VIEW;
  324. paramBText->horzAlignment = NVG_ALIGN_CENTER;
  325. paramBText->colorHandle = &module->textColor;
  326. paramBText->setFont(DynamicText::FontMode::FONT_MODE_7SEG);
  327. for(auto i = 0; i < VecAmalgam::NUM_MODES; ++i) {
  328. paramBText->addItem(module->paramBNames[i]);
  329. }
  330. addChild(paramBText);
  331. }
  332. {
  333. DynamicFrameText* paramBBlurText = new DynamicFrameText;
  334. paramBBlurText->size = 12;
  335. paramBBlurText->blur = 8.f;
  336. paramBBlurText->box.pos = Vec(75, 249);
  337. paramBBlurText->box.size = Vec(82, 14);
  338. paramBBlurText->itemHandle = &module->iAmalgamType;
  339. paramBBlurText->visibility = nullptr;
  340. paramBBlurText->viewMode = ACTIVE_LOW_VIEW;
  341. paramBBlurText->horzAlignment = NVG_ALIGN_CENTER;
  342. paramBBlurText->customColor = nvgRGB(0xFF, 0x7F, 0x7F);
  343. paramBBlurText->setFont(DynamicText::FontMode::FONT_MODE_7SEG);
  344. for(auto i = 0; i < VecAmalgam::NUM_MODES; ++i) {
  345. paramBBlurText->addItem(module->paramBNames[i]);
  346. }
  347. addChild(paramBBlurText);
  348. }
  349. addParam(ParamWidget::create<LightLEDButton>(DCCoupleLightPos, module, Amalgam::DC_COUPLE_PARAM, 0.f, 1.f, 0.f));
  350. addChild(ModuleLightWidget::create<MediumLight<RedLight>>(DCCoupleLightPos.plus(Vec(2.5f, 2.5f)), module, Amalgam::DC_COUPLE_LIGHT));
  351. }
  352. void AmalgamWidget::appendContextMenu(Menu *menu) {
  353. Amalgam *module = dynamic_cast<Amalgam*>(this->module);
  354. assert(module);
  355. menu->addChild(construct<MenuLabel>());
  356. menu->addChild(construct<MenuLabel>(&MenuLabel::text, "Panel style"));
  357. menu->addChild(construct<AmalgamPanelStyleItem>(&MenuItem::text, "Dark", &AmalgamPanelStyleItem::module,
  358. module, &AmalgamPanelStyleItem::panelStyle, 0));
  359. menu->addChild(construct<AmalgamPanelStyleItem>(&MenuItem::text, "Light", &AmalgamPanelStyleItem::module,
  360. module, &AmalgamPanelStyleItem::panelStyle, 1));
  361. }
  362. RACK_PLUGIN_MODEL_INIT(Valley, Amalgam) {
  363. Model *modelAmalgam = Model::create<Amalgam, AmalgamWidget>(TOSTRING(SLUG), "Amalgam", "Amalgam", RING_MODULATOR_TAG, EFFECT_TAG, WAVESHAPER_TAG);
  364. return modelAmalgam;
  365. }