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.

434 lines
13KB

  1. // Copyright 2013 Olivier Gillet.
  2. //
  3. // Author: Olivier Gillet (ol.gillet@gmail.com)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. // See http://creativecommons.org/licenses/MIT/ for more information.
  24. //
  25. // -----------------------------------------------------------------------------
  26. //
  27. // User interface.
  28. #include "frames/ui.h"
  29. #include <algorithm>
  30. #include "frames/keyframer.h"
  31. #include "frames/poly_lfo.h"
  32. namespace frames {
  33. using namespace std;
  34. using namespace stmlib;
  35. const uint16_t kAdcThreshold = 1 << (16 - 10); // 10 bits
  36. const int32_t kLongPressDuration = 800;
  37. const int32_t kVeryLongPressDuration = 3000;
  38. const uint16_t kKeyframeGridTolerance = 2048;
  39. void Ui::Init(Keyframer* keyframer, PolyLfo* poly_lfo) {
  40. factory_testing_switch_.Init();
  41. channel_leds_.Init();
  42. keyframe_led_.Init();
  43. rgb_led_.Init();
  44. switches_.Init();
  45. adc_.Init(false);
  46. fill(&adc_value_[0], &adc_value_[kNumAdcChannels], 0);
  47. keyframer_ = keyframer;
  48. poly_lfo_ = poly_lfo;
  49. mode_ = factory_testing_switch_.Read()
  50. ? UI_MODE_SPLASH
  51. : UI_MODE_FACTORY_TESTING;
  52. animation_counter_ = 0;
  53. FindNearestKeyframe();
  54. active_keyframe_lock_ = false;
  55. uint32_t ui_flags = keyframer_->extra_settings();
  56. poly_lfo_mode_ = ui_flags & 1;
  57. sequencer_mode_= ui_flags & 2;
  58. secret_handshake_counter_ = 0;
  59. }
  60. void Ui::TryCalibration() {
  61. if (switches_.pressed_immediate(1)) {
  62. keyframer_->Calibrate(frame_modulation());
  63. FlushEvents();
  64. }
  65. }
  66. void Ui::Poll() {
  67. switches_.Debounce();
  68. for (uint8_t i = 0; i < kNumSwitches; ++i) {
  69. if (switches_.just_pressed(i)) {
  70. queue_.AddEvent(CONTROL_SWITCH, i, 0);
  71. press_time_[i] = system_clock.milliseconds();
  72. detect_very_long_press_[i] = false;
  73. }
  74. if (switches_.pressed(i)) {
  75. int32_t pressed_time = system_clock.milliseconds() - press_time_[i];
  76. if (!detect_very_long_press_[i]) {
  77. if (pressed_time > kLongPressDuration) {
  78. queue_.AddEvent(CONTROL_SWITCH, i, pressed_time);
  79. detect_very_long_press_[i] = true;
  80. }
  81. } else {
  82. if (pressed_time > kVeryLongPressDuration) {
  83. queue_.AddEvent(CONTROL_SWITCH, i, pressed_time);
  84. detect_very_long_press_[i] = false;
  85. press_time_[i] = 0;
  86. }
  87. }
  88. }
  89. if (switches_.released(i) &&
  90. press_time_[i] != 0 &&
  91. !detect_very_long_press_[i]) {
  92. queue_.AddEvent(
  93. CONTROL_SWITCH,
  94. i,
  95. system_clock.milliseconds() - press_time_[i] + 1);
  96. press_time_[i] = 0;
  97. detect_very_long_press_[i] = false;
  98. }
  99. }
  100. for (uint8_t i = 0; i <= kFrameAdcChannel; ++i) {
  101. int32_t value = (31 * adc_filtered_value_[i] + adc_.value(i)) >> 5;
  102. adc_filtered_value_[i] = value;
  103. int32_t current_value = static_cast<int32_t>(adc_value_[i]);
  104. if (value >= current_value + kAdcThreshold ||
  105. value <= current_value - kAdcThreshold) {
  106. queue_.AddEvent(CONTROL_POT, i, value);
  107. adc_value_[i] = value;
  108. }
  109. }
  110. switch (mode_) {
  111. case UI_MODE_SPLASH:
  112. animation_counter_ += 128;
  113. channel_leds_.set_channel(0, (animation_counter_ + 49152) >> 8);
  114. channel_leds_.set_channel(1, (animation_counter_ + 32768) >> 8);
  115. channel_leds_.set_channel(2, (animation_counter_ + 16384) >> 8);
  116. channel_leds_.set_channel(3, (animation_counter_ + 0) >> 8);
  117. rgb_led_.set_color(255, 255, 255);
  118. break;
  119. case UI_MODE_SAVE_CONFIRMATION:
  120. animation_counter_ -= 256;
  121. channel_leds_.set_channel(0, (animation_counter_ + 0) >> 8);
  122. channel_leds_.set_channel(1, (animation_counter_ + 16384) >> 8);
  123. channel_leds_.set_channel(2, (animation_counter_ + 32768) >> 8);
  124. channel_leds_.set_channel(3, (animation_counter_ + 49152) >> 8);
  125. rgb_led_.set_color(0, 255, 0);
  126. break;
  127. case UI_MODE_ERASE_CONFIRMATION:
  128. animation_counter_ -= 256;
  129. channel_leds_.set_channel(0, (animation_counter_ + 0) >> 8);
  130. channel_leds_.set_channel(1, (animation_counter_ + 16384) >> 8);
  131. channel_leds_.set_channel(2, (animation_counter_ + 32768) >> 8);
  132. channel_leds_.set_channel(3, (animation_counter_ + 49152) >> 8);
  133. rgb_led_.set_color(255, 0, 0);
  134. break;
  135. case UI_MODE_FACTORY_TESTING:
  136. channel_leds_.set_channel(0, keyframer_->level(0) >> 8);
  137. channel_leds_.set_channel(1, keyframer_->level(1) >> 8);
  138. channel_leds_.set_channel(2, keyframer_->level(2) >> 8);
  139. channel_leds_.set_channel(3, keyframer_->level(3) >> 8);
  140. if (frame() < 4096) {
  141. rgb_led_.set_color(255, 0, 0);
  142. } else if (frame() > 61440) {
  143. rgb_led_.set_color(0, 255, 0);
  144. } else {
  145. uint8_t v = frame_modulation() >> 8;
  146. rgb_led_.set_color(0, 0, v);
  147. }
  148. if (test_led_) {
  149. keyframe_led_.High();
  150. } else {
  151. keyframe_led_.Low();
  152. }
  153. break;
  154. case UI_MODE_NORMAL:
  155. channel_leds_.set_channel(0, keyframer_->level(0) >> 8);
  156. channel_leds_.set_channel(1, keyframer_->level(1) >> 8);
  157. channel_leds_.set_channel(2, keyframer_->level(2) >> 8);
  158. channel_leds_.set_channel(3, keyframer_->level(3) >> 8);
  159. rgb_led_.set_color(keyframer_->color());
  160. if (active_keyframe_ == -1) {
  161. keyframe_led_.Low();
  162. } else {
  163. animation_counter_ += 256;
  164. int32_t distance = frame() - \
  165. keyframer_->keyframe(active_keyframe_).timestamp;
  166. distance = min(distance * distance >> 18, int32_t(15));
  167. ++keyframe_led_pwm_counter_;
  168. if ((keyframe_led_pwm_counter_ & 15) >= distance) {
  169. keyframe_led_.High();
  170. } else {
  171. keyframe_led_.Low();
  172. }
  173. if (active_keyframe_lock_) {
  174. if (animation_counter_ & 0x8000) {
  175. keyframe_led_.High();
  176. } else {
  177. keyframe_led_.Low();
  178. }
  179. }
  180. }
  181. if (poly_lfo_mode_) {
  182. channel_leds_.set_channel(0, poly_lfo_->level(0));
  183. channel_leds_.set_channel(1, poly_lfo_->level(1));
  184. channel_leds_.set_channel(2, poly_lfo_->level(2));
  185. channel_leds_.set_channel(3, poly_lfo_->level(3));
  186. rgb_led_.set_color(poly_lfo_->color());
  187. if (poly_lfo_->level(0) > 128) {
  188. keyframe_led_.High();
  189. } else {
  190. keyframe_led_.Low();
  191. }
  192. }
  193. break;
  194. case UI_MODE_EDIT_RESPONSE:
  195. case UI_MODE_EDIT_EASING:
  196. {
  197. animation_counter_ += 48;
  198. for (uint8_t i = 0; i < 4; ++i) {
  199. channel_leds_.set_channel(i, active_channel_ == i ? 255 : 0);
  200. }
  201. if (mode_ == UI_MODE_EDIT_EASING) {
  202. rgb_led_.set_color(255, 16, 32);
  203. } else {
  204. rgb_led_.set_color(16, 192, 32);
  205. }
  206. uint16_t brightness = active_channel_ == -1
  207. ? 65535
  208. : keyframer_->SampleAnimation(active_channel_,
  209. animation_counter_,
  210. mode_ == UI_MODE_EDIT_EASING);
  211. rgb_led_.Dim(brightness);
  212. }
  213. break;
  214. }
  215. rgb_led_.Write();
  216. channel_leds_.Write();
  217. }
  218. void Ui::FlushEvents() {
  219. queue_.Flush();
  220. }
  221. void Ui::OnSwitchPressed(const Event& e) {
  222. test_led_ = true;
  223. }
  224. void Ui::OnSwitchReleased(const Event& e) {
  225. if (mode_ == UI_MODE_FACTORY_TESTING) {
  226. test_led_ = false;
  227. } else {
  228. if (active_keyframe_lock_) {
  229. active_keyframe_lock_ = false;
  230. FindNearestKeyframe();
  231. return;
  232. }
  233. switch (e.control_id) {
  234. case SWITCH_ADD_FRAME:
  235. if (e.data > kVeryLongPressDuration) {
  236. uint32_t ui_flags = 0;
  237. ui_flags |= poly_lfo_mode_ ? 1 : 0;
  238. ui_flags |= sequencer_mode_ ? 2 : 0;
  239. keyframer_->Save(ui_flags);
  240. mode_ = UI_MODE_SAVE_CONFIRMATION;
  241. } else if (e.data > kLongPressDuration) {
  242. if (!poly_lfo_mode_) {
  243. mode_ = UI_MODE_EDIT_EASING;
  244. active_channel_ = -1;
  245. }
  246. } else {
  247. if (mode_ == UI_MODE_NORMAL && !poly_lfo_mode_) {
  248. if (active_keyframe_ == -1) {
  249. keyframer_->AddKeyframe(frame(), &adc_value_[0]);
  250. } else {
  251. ++secret_handshake_counter_;
  252. if (secret_handshake_counter_ >= 5) {
  253. sequencer_mode_ = !sequencer_mode_;
  254. }
  255. // This abandoned feature allowed to select and continue editing
  256. // a keyframe with the 4 knobs on the top even when the big
  257. // frame knob is being played. For that, we select the keyframe
  258. // we are interested in, we press "add", and this "locks" the
  259. // 4 pots at the top of the module for editing this keyframe.
  260. //active_keyframe_lock_ = true;
  261. }
  262. FindNearestKeyframe();
  263. } else {
  264. mode_ = UI_MODE_NORMAL;
  265. }
  266. }
  267. break;
  268. case SWITCH_DELETE_FRAME:
  269. if (frame() < 128) {
  270. --secret_handshake_counter_;
  271. if (secret_handshake_counter_ <= -10) {
  272. poly_lfo_mode_ = !poly_lfo_mode_;
  273. secret_handshake_counter_ = 0;
  274. }
  275. }
  276. if (e.data > kVeryLongPressDuration) {
  277. keyframer_->Clear();
  278. FindNearestKeyframe();
  279. SyncWithPots();
  280. poly_lfo_mode_ = false;
  281. mode_ = UI_MODE_ERASE_CONFIRMATION;
  282. } else if (e.data > kLongPressDuration) {
  283. if (!poly_lfo_mode_) {
  284. mode_ = UI_MODE_EDIT_RESPONSE;
  285. active_channel_ = -1;
  286. }
  287. } else {
  288. if (mode_ == UI_MODE_NORMAL && !poly_lfo_mode_) {
  289. if (active_keyframe_ != -1) {
  290. keyframer_->RemoveKeyframe(
  291. keyframer_->keyframe(active_keyframe_).timestamp);
  292. }
  293. FindNearestKeyframe();
  294. SyncWithPots();
  295. } else {
  296. mode_ = UI_MODE_NORMAL;
  297. }
  298. }
  299. break;
  300. }
  301. }
  302. }
  303. void Ui::OnPotChanged(const Event& e) {
  304. if (mode_ == UI_MODE_FACTORY_TESTING) {
  305. switch (e.control_id) {
  306. case 0:
  307. case 1:
  308. case 2:
  309. case 3:
  310. keyframer_->set_immediate(e.control_id, e.data);
  311. break;
  312. }
  313. } else if (poly_lfo_mode_) {
  314. switch (e.control_id) {
  315. case 0:
  316. poly_lfo_->set_shape(e.data);
  317. break;
  318. case 1:
  319. poly_lfo_->set_shape_spread(e.data);
  320. break;
  321. case 2:
  322. poly_lfo_->set_spread(e.data);
  323. break;
  324. case 3:
  325. poly_lfo_->set_coupling(e.data);
  326. break;
  327. }
  328. } else {
  329. switch (e.control_id) {
  330. case 0:
  331. case 1:
  332. case 2:
  333. case 3:
  334. if (mode_ == UI_MODE_NORMAL || mode_ == UI_MODE_SPLASH) {
  335. if (active_keyframe_ != -1) {
  336. Keyframe* k = keyframer_->mutable_keyframe(active_keyframe_);
  337. k->values[e.control_id] = e.data;
  338. } else {
  339. keyframer_->set_immediate(e.control_id, e.data);
  340. }
  341. } else if (mode_ == UI_MODE_EDIT_RESPONSE) {
  342. active_channel_ = e.control_id;
  343. keyframer_->mutable_settings(e.control_id)->response = e.data >> 8;
  344. } else if (mode_ == UI_MODE_EDIT_EASING) {
  345. active_channel_ = e.control_id;
  346. keyframer_->mutable_settings(e.control_id)->easing_curve = \
  347. static_cast<EasingCurve>(e.data * 6 >> 16);
  348. }
  349. break;
  350. case kFrameAdcChannel:
  351. if (!active_keyframe_lock_) {
  352. FindNearestKeyframe();
  353. }
  354. break;
  355. case kFrameModulationAdcChannel:
  356. break;
  357. }
  358. }
  359. }
  360. void Ui::FindNearestKeyframe() {
  361. active_keyframe_ = keyframer_->FindNearestKeyframe(
  362. frame(),
  363. kKeyframeGridTolerance);
  364. }
  365. void Ui::SyncWithPots() {
  366. if (!keyframer_->num_keyframes()) {
  367. for (uint8_t i = 0; i < kNumChannels; ++i) {
  368. keyframer_->set_immediate(i, adc_filtered_value_[i]);
  369. }
  370. }
  371. }
  372. void Ui::DoEvents() {
  373. while (queue_.available()) {
  374. Event e = queue_.PullEvent();
  375. if (e.control_type == CONTROL_SWITCH) {
  376. if (e.data == 0) {
  377. OnSwitchPressed(e);
  378. } else {
  379. OnSwitchReleased(e);
  380. }
  381. } else if (e.control_type == CONTROL_POT) {
  382. OnPotChanged(e);
  383. }
  384. }
  385. if (queue_.idle_time() > 500) {
  386. queue_.Touch();
  387. if (mode_ == UI_MODE_SPLASH
  388. || mode_ == UI_MODE_SAVE_CONFIRMATION
  389. || mode_ == UI_MODE_ERASE_CONFIRMATION) {
  390. mode_ = UI_MODE_NORMAL;
  391. }
  392. secret_handshake_counter_ = 0;
  393. }
  394. }
  395. } // namespace frames