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.

128 lines
2.9KB

  1. #include "turing-module.hh"
  2. #include <cmath>
  3. namespace rack_plugin_Skylights {
  4. const double SEMITONE = 1.0 / 12.0;
  5. void turing_module::step() {
  6. double mode;
  7. if (inputs[I_MODE].active)
  8. mode = inputs[I_MODE].value;
  9. else
  10. mode = params[P_MODE].value;
  11. bool hot = m_sequence & 0x1;
  12. outputs[O_GATE].value = hot ? 10.0 : 0.0;
  13. outputs[O_PULSE].value =
  14. min(outputs[O_GATE].value * inputs[I_CLOCK].value, 10.0);
  15. // check for clock advance
  16. auto was_high = m_clock_trigger.isHigh();
  17. m_clock_trigger.process(inputs[I_CLOCK].value);
  18. if (!was_high && was_high != m_clock_trigger.isHigh()) {
  19. // clock was advanced
  20. // write knob always zeroes our input
  21. if (params[P_WRITE].value > 0.9) hot = false;
  22. else if (mode > 0.9) {
  23. // leave hot alone
  24. } else if (mode > 0.55) {
  25. // inverts about 13% of the time
  26. const size_t TRIES = 3;
  27. bool should_flip = true;
  28. for (size_t i = 0;
  29. i <= TRIES;
  30. i++)
  31. {
  32. should_flip = (should_flip == m_spigot.next());
  33. if (!should_flip) break;
  34. }
  35. hot = should_flip ? !hot : hot;
  36. } else if (mode > 0.10) {
  37. // 50/50 invert
  38. bool should_invert = m_spigot.next();
  39. hot = should_invert ? !hot : hot;
  40. } else {
  41. // always invert
  42. hot = !hot;
  43. }
  44. // compute an advance mask based on step length, [2, 16)
  45. uint16_t mask = 0;
  46. size_t steps = 0;
  47. for (double i = 0;
  48. i < params[P_LENGTH].value;
  49. i += 1)
  50. {
  51. mask <<= 1;
  52. mask |= 0x1;
  53. steps++;
  54. }
  55. uint16_t seq = m_sequence & mask;
  56. seq >>= 1;
  57. seq |= (hot ? 1 : 0) << (steps - 1);
  58. m_sequence &= ~mask;
  59. m_sequence += seq;
  60. uint8_t signal_d = m_sequence & 0xFF;
  61. double signal_a = (((double)signal_d) / 255.0);
  62. outputs[O_VOLTAGE].value =
  63. (signal_a * params[P_SCALE].value) // signal scaled by scale knob
  64. - (5.0 * params[P_POLE].value); // shift to bi-polar on request
  65. // expander is always 10v unipolar
  66. outputs[O_EXPANSION].value = (((double)m_sequence) / 65535.0) * 10.0;
  67. for (size_t i = 0;
  68. i < 8;
  69. i++)
  70. {
  71. lights[L_LIGHT8-i].value = ((m_sequence & (1 << i)) > 0) ? 1.0 : 0.0;
  72. }
  73. }
  74. }
  75. turing_module::turing_module() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS), m_sequence(0) {
  76. }
  77. turing_module::~turing_module() {
  78. }
  79. json_t* turing_module::toJson() {
  80. auto map = json_object();
  81. json_object_set_new(map, "sequence", json_integer(m_sequence));
  82. return map;
  83. }
  84. void turing_module::fromJson(json_t *root) {
  85. if (!root) return;
  86. auto seqo = json_object_get(root, "sequence");
  87. if (json_is_number(seqo)) {
  88. m_sequence = (uint16_t)json_integer_value(seqo);
  89. }
  90. }
  91. void turing_module::onReset() {
  92. Module::onReset();
  93. m_sequence = 0;
  94. }
  95. void turing_module::onRandomize() {
  96. Module::onRandomize();
  97. m_sequence = 0;
  98. for (size_t i = 0;
  99. i < 16;
  100. i++)
  101. {
  102. m_sequence += m_spigot.next() << i;
  103. }
  104. }
  105. } // namespace rack_plugin_Skylights