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.

332 lines
8.4KB

  1. ///////////////////////////////////////////////////
  2. //
  3. // Clock Divider VCV Module
  4. // Based on autodafe's clock divider but code cleaned up and extra outputs added.
  5. //
  6. // Strum 2017
  7. //
  8. ///////////////////////////////////////////////////
  9. #include "mental.hpp"
  10. #include "dsp/digital.hpp"
  11. namespace rack_plugin_mental {
  12. ////////////////////////////////////////////////
  13. struct MentalClockDivider : Module {
  14. enum ParamIds {
  15. RESET_PARAM,
  16. NUM_PARAMS
  17. };
  18. enum InputIds {
  19. CLOCK_INPUT,
  20. RESET_INPUT,
  21. NUM_INPUTS
  22. };
  23. enum OutputIds {
  24. OUT1,
  25. OUT2,
  26. OUT4,
  27. OUT8,
  28. OUT16,
  29. OUT32,
  30. OUT3,
  31. OUT5,
  32. OUT7,
  33. OUT12,
  34. NUM_OUTPUTS
  35. };
  36. enum LightIds {
  37. LIGHTS,
  38. NUM_LIGHTS = LIGHTS + 10
  39. };
  40. int clock2Count = 0;
  41. int clock4Count = 0;
  42. int clock8Count = 0;
  43. int clock16Count = 0;
  44. int clock32Count = 0;
  45. int clock3Count = 0;
  46. int clock5Count = 0;
  47. int clock7Count = 0;
  48. int clock12Count = 0;
  49. SchmittTrigger trigger2;
  50. SchmittTrigger trigger4;
  51. SchmittTrigger trigger8;
  52. SchmittTrigger trigger16;
  53. SchmittTrigger trigger32;
  54. SchmittTrigger trigger3;
  55. SchmittTrigger trigger5;
  56. SchmittTrigger trigger7;
  57. SchmittTrigger trigger12;
  58. SchmittTrigger reset_trig;
  59. MentalClockDivider();
  60. void step() override;
  61. };
  62. ////////////////////////////////////////////////////////////////
  63. MentalClockDivider::MentalClockDivider() {
  64. params.resize(NUM_PARAMS);
  65. inputs.resize(NUM_INPUTS);
  66. outputs.resize(NUM_OUTPUTS);
  67. lights.resize(NUM_LIGHTS);
  68. }
  69. int divider2 = 2;
  70. int divider4 = 4;
  71. int divider8 = 8;
  72. int divider16 = 16;
  73. int divider32 = 32;
  74. int divider3 = 3;
  75. int divider5 = 5;
  76. int divider7 = 7;
  77. int divider12 = 12;
  78. //////////////////////////////////////////////////////////////////////////////////
  79. void MentalClockDivider::step()
  80. {
  81. bool reset = false;
  82. if (reset_trig.process(params[RESET_PARAM].value))
  83. {
  84. clock2Count = 0;
  85. clock4Count = 0;
  86. clock8Count = 0;
  87. clock16Count = 0;
  88. clock32Count = 0;
  89. clock3Count = 0;
  90. clock5Count = 0;
  91. clock7Count = 0;
  92. clock12Count = 0;
  93. reset = true;
  94. }
  95. if (clock2Count >= divider2)
  96. {
  97. clock2Count = 0;
  98. reset = true;
  99. }
  100. if (clock4Count >= divider4)
  101. {
  102. clock4Count = 0;
  103. reset = true;
  104. }
  105. if (clock8Count >= divider8)
  106. {
  107. clock8Count = 0;
  108. reset = true;
  109. }
  110. if (clock16Count >= divider16)
  111. {
  112. clock16Count = 0;
  113. reset = true;
  114. }
  115. if (clock32Count >= divider32)
  116. {
  117. clock32Count = 0;
  118. reset = true;
  119. }
  120. if (clock3Count >= divider3)
  121. {
  122. clock3Count = 0;
  123. reset = true;
  124. }
  125. if (clock5Count >= divider5)
  126. {
  127. clock5Count = 0;
  128. reset = true;
  129. }
  130. if (clock7Count >= divider7)
  131. {
  132. clock7Count = 0;
  133. reset = true;
  134. }
  135. if (clock12Count >= divider12)
  136. {
  137. clock12Count = 0;
  138. reset = true;
  139. }
  140. /////////////////////////////////////////////////////////////
  141. if (clock2Count < divider2 / 2)
  142. {
  143. outputs[OUT2].value= 10.0;
  144. if (clock2Count == 0)
  145. {
  146. lights[LIGHTS].value = 1.0;
  147. }
  148. else
  149. {
  150. // sample rate has changed, update this.
  151. //lights[0] -= lights[0] / lightLambda / gSampleRate;
  152. //lights[0] -= lights[0] / lightLambda / engineGetSampleRate();
  153. lights[LIGHTS].value = 0.0;
  154. }
  155. }
  156. else
  157. {
  158. outputs[OUT2].value= 0.0;
  159. lights[LIGHTS].value = 0.0;
  160. }
  161. if (clock4Count < divider4 / 2)
  162. {
  163. outputs[OUT4].value= 10.0;
  164. if (clock4Count == 0)
  165. {
  166. lights[LIGHTS + 1].value = 1.0;
  167. }
  168. else
  169. {
  170. lights[LIGHTS + 1].value = 0.0;
  171. }
  172. }
  173. else
  174. {
  175. outputs[OUT4].value= 0.0;
  176. lights[LIGHTS + 1].value = 0.0;
  177. }
  178. if (clock8Count < divider8 / 2)
  179. {
  180. outputs[OUT8].value= 10.0;
  181. if (clock8Count == 0)
  182. {
  183. lights[LIGHTS + 2].value = 1.0;
  184. }
  185. else
  186. {
  187. lights[LIGHTS + 2].value = 0.0;
  188. }
  189. }
  190. else
  191. {
  192. outputs[OUT8].value= 0.0;
  193. lights[LIGHTS + 2].value = 1.0;
  194. }
  195. if (clock16Count < divider16 / 2)
  196. {
  197. outputs[OUT16].value= 10.0;
  198. if (clock16Count == 0)
  199. {
  200. lights[LIGHTS + 3].value = 1.0;
  201. }
  202. else
  203. {
  204. lights[LIGHTS + 3].value = 0.0;
  205. }
  206. }
  207. else
  208. {
  209. outputs[OUT16].value= 0.0;
  210. lights[LIGHTS + 3].value = 0.0;
  211. }
  212. if (clock32Count < divider32 / 2)
  213. {
  214. outputs[OUT32].value= 10.0;
  215. if (clock16Count == 0)
  216. {
  217. lights[LIGHTS + 4].value = 1.0;
  218. }
  219. else
  220. {
  221. lights[LIGHTS + 4].value = 0.0;
  222. }
  223. }
  224. else
  225. {
  226. outputs[OUT32].value= 0.0;
  227. lights[LIGHTS + 4].value = 0.0;
  228. }
  229. if (clock3Count < divider3 / 2) outputs[OUT3].value = 10.0; else outputs[OUT3].value = 0.0;
  230. if (clock5Count < divider5 / 2) outputs[OUT5].value = 10.0; else outputs[OUT5].value = 0.0;
  231. if (clock7Count < divider7 / 2) outputs[OUT7].value = 10.0; else outputs[OUT7].value = 0.0;
  232. if (clock12Count <divider12/2) outputs[OUT12].value = 10.0; else outputs[OUT12].value = 0.0;
  233. //////////////////////////////////////////////////////////////////////////////
  234. if (reset == false)
  235. {
  236. if (trigger2.process(inputs[CLOCK_INPUT].value) && clock2Count <= divider2)
  237. clock2Count++;
  238. if (trigger4.process(inputs[CLOCK_INPUT].value) && clock4Count <= divider4)
  239. clock4Count++;
  240. if (trigger8.process(inputs[CLOCK_INPUT].value) && clock8Count <= divider8)
  241. clock8Count++;
  242. if (trigger16.process(inputs[CLOCK_INPUT].value) && clock16Count <= divider16)
  243. clock16Count++;
  244. if (trigger32.process(inputs[CLOCK_INPUT].value) && clock32Count <= divider32)
  245. clock32Count++;
  246. if (trigger3.process(inputs[CLOCK_INPUT].value) && clock3Count <= divider3)
  247. clock3Count++;
  248. if (trigger5.process(inputs[CLOCK_INPUT].value) && clock5Count <= divider5)
  249. clock5Count++;
  250. if (trigger7.process(inputs[CLOCK_INPUT].value) && clock7Count <= divider7)
  251. clock7Count++;
  252. if (trigger12.process(inputs[CLOCK_INPUT].value) && clock12Count <= divider12)
  253. clock12Count++;
  254. }
  255. }
  256. /////////////////////////////////////////////////////////////////////////////////////
  257. struct MentalClockDividerWidget : ModuleWidget {
  258. MentalClockDividerWidget(MentalClockDivider *module);
  259. };
  260. MentalClockDividerWidget::MentalClockDividerWidget(MentalClockDivider *module) : ModuleWidget(module)
  261. {
  262. setPanel(SVG::load(assetPlugin(plugin, "res/MentalClockDivider.svg")));
  263. addInput(Port::create<GateInPort>(Vec(3, 20), Port::INPUT, module, MentalClockDivider::CLOCK_INPUT));
  264. addInput(Port::create<GateInPort>(Vec(3, 55), Port::INPUT, module, MentalClockDivider::RESET_INPUT));
  265. addParam(ParamWidget::create<LEDButton>(Vec(5, 80), module, MentalClockDivider::RESET_PARAM, 0.0, 1.0, 0.0));
  266. addOutput(Port::create<GateOutPort>(Vec(2, 120), Port::OUTPUT, module, MentalClockDivider::OUT2));
  267. addOutput(Port::create<GateOutPort>(Vec(2, 145), Port::OUTPUT, module, MentalClockDivider::OUT4));
  268. addOutput(Port::create<GateOutPort>(Vec(2, 170), Port::OUTPUT, module, MentalClockDivider::OUT8));
  269. addOutput(Port::create<GateOutPort>(Vec(2, 195), Port::OUTPUT, module, MentalClockDivider::OUT16));
  270. addOutput(Port::create<GateOutPort>(Vec(2, 220), Port::OUTPUT, module, MentalClockDivider::OUT32));
  271. addOutput(Port::create<GateOutPort>(Vec(2, 250), Port::OUTPUT, module, MentalClockDivider::OUT3));
  272. addOutput(Port::create<GateOutPort>(Vec(2, 275), Port::OUTPUT, module, MentalClockDivider::OUT5));
  273. addOutput(Port::create<GateOutPort>(Vec(2, 300), Port::OUTPUT, module, MentalClockDivider::OUT7));
  274. addOutput(Port::create<GateOutPort>(Vec(2, 325), Port::OUTPUT, module, MentalClockDivider::OUT12));
  275. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(33, 120), module, MentalClockDivider::LIGHTS));
  276. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(33, 145), module, MentalClockDivider::LIGHTS+1));
  277. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(33, 170), module, MentalClockDivider::LIGHTS+2));
  278. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(33, 195), module, MentalClockDivider::LIGHTS+3));
  279. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(33, 220), module, MentalClockDivider::LIGHTS+4));
  280. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(33, 255), module, MentalClockDivider::LIGHTS+5));
  281. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(33, 275), module, MentalClockDivider::LIGHTS+6));
  282. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(33, 305), module, MentalClockDivider::LIGHTS+7));
  283. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(33, 330), module, MentalClockDivider::LIGHTS+8));
  284. }
  285. } // namespace rack_plugin_mental
  286. using namespace rack_plugin_mental;
  287. RACK_PLUGIN_MODEL_INIT(mental, MentalClockDivider) {
  288. Model *modelMentalClockDivider = Model::create<MentalClockDivider, MentalClockDividerWidget>("mental", "MentalClockDivider", "Clock Divider", UTILITY_TAG);
  289. return modelMentalClockDivider;
  290. }