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.

780 lines
24KB

  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. #include "frames/euclidean.h"
  33. namespace frames {
  34. using namespace std;
  35. using namespace stmlib;
  36. const uint16_t kAdcThreshold = 1 << (16 - 10); // 10 bits
  37. const int32_t kLongPressDuration = 800;
  38. const int32_t kVeryLongPressDuration = 2000;
  39. const uint16_t kKeyframeGridTolerance = 2048;
  40. const uint8_t kDividersSteps = 7;
  41. const uint16_t kDeadZone = 2048; // 0..32767
  42. void Ui::Init(Keyframer* keyframer, PolyLfo* poly_lfo, Euclidean euclidean[kNumChannels]) {
  43. factory_testing_switch_.Init();
  44. channel_leds_.Init();
  45. keyframe_led_.Init();
  46. rgb_led_.Init();
  47. switches_.Init();
  48. adc_.Init(false);
  49. fill(&adc_value_[0], &adc_value_[kNumAdcChannels], 0);
  50. keyframer_ = keyframer;
  51. poly_lfo_ = poly_lfo;
  52. euclidean_ = euclidean;
  53. mode_ = factory_testing_switch_.Read()
  54. ? UI_MODE_SPLASH
  55. : UI_MODE_FACTORY_TESTING;
  56. animation_counter_ = 0;
  57. ignore_releases_ = 0;
  58. active_slot_ = 0;
  59. FindNearestKeyframe();
  60. active_keyframe_lock_ = false;
  61. feature_mode_ = static_cast<FeatureMode>(keyframer_->feature_mode_);
  62. for (int i=0; i<kNumChannels; i++) {
  63. euclidean_[i].set_length(keyframer_->euclidean_length_[i]);
  64. euclidean_[i].set_shape(keyframer_->euclidean_shape_[i]);
  65. }
  66. sequencer_step = 0;
  67. step_divider = 1;
  68. step_random = 0;
  69. shift_divider = 1;
  70. shift_random = 0;
  71. feedback_random = 0;
  72. active_registers = kMaxRegisters;
  73. for (int i=0; i<kMaxRegisters; i++)
  74. shift_register[i] = 0;
  75. }
  76. void Ui::TryCalibration() {
  77. if (switches_.pressed_immediate(1)) {
  78. keyframer_->Calibrate(frame_modulation());
  79. FlushEvents();
  80. }
  81. }
  82. void Ui::Poll() {
  83. switches_.Debounce();
  84. for (uint8_t i = 0; i < kNumSwitches; ++i) {
  85. if (switches_.just_pressed(i)) {
  86. queue_.AddEvent(CONTROL_SWITCH, i, 0);
  87. press_time_[i] = system_clock.milliseconds();
  88. detect_very_long_press_[i] = false;
  89. }
  90. if (switches_.pressed(i)) {
  91. int32_t pressed_time = system_clock.milliseconds() - press_time_[i];
  92. if (!detect_very_long_press_[i]) {
  93. if (pressed_time > kLongPressDuration) {
  94. queue_.AddEvent(CONTROL_SWITCH, i, pressed_time);
  95. detect_very_long_press_[i] = true;
  96. }
  97. } else {
  98. if (pressed_time > kVeryLongPressDuration) {
  99. queue_.AddEvent(CONTROL_SWITCH, i, pressed_time);
  100. detect_very_long_press_[i] = false;
  101. press_time_[i] = 0;
  102. }
  103. }
  104. }
  105. if (switches_.released(i) &&
  106. press_time_[i] != 0 &&
  107. !detect_very_long_press_[i]) {
  108. queue_.AddEvent(
  109. CONTROL_SWITCH,
  110. i,
  111. system_clock.milliseconds() - press_time_[i] + 1);
  112. press_time_[i] = 0;
  113. detect_very_long_press_[i] = false;
  114. }
  115. }
  116. for (uint8_t i = 0; i <= kFrameAdcChannel; ++i) {
  117. int32_t value = (31 * adc_filtered_value_[i] + adc_.value(i)) >> 5;
  118. adc_filtered_value_[i] = value;
  119. int32_t current_value = static_cast<int32_t>(adc_value_[i]);
  120. if (value >= current_value + kAdcThreshold ||
  121. value <= current_value - kAdcThreshold) {
  122. queue_.AddEvent(CONTROL_POT, i, value);
  123. adc_value_[i] = value;
  124. }
  125. }
  126. switch (mode_) {
  127. case UI_MODE_SPLASH:
  128. animation_counter_ += 128;
  129. channel_leds_.set_channel(0, (animation_counter_ + 49152) >> 8);
  130. channel_leds_.set_channel(1, (animation_counter_ + 32768) >> 8);
  131. channel_leds_.set_channel(2, (animation_counter_ + 16384) >> 8);
  132. channel_leds_.set_channel(3, (animation_counter_ + 0) >> 8);
  133. rgb_led_.set_color(255, 255, 255);
  134. break;
  135. case UI_MODE_FEATURE_SWITCH:
  136. animation_counter_ += 1024;
  137. rgb_led_.set_color(255, 255, 255);
  138. rgb_led_.Dim(animation_counter_);
  139. for (int i=0; i<4; i++)
  140. channel_leds_.set_channel(i, 0);
  141. switch (feature_mode_) {
  142. case FEAT_MODE_KEYFRAMER:
  143. break;
  144. case FEAT_MODE_KEYFRAME_LOOPER:
  145. rgb_led_.set_color(255, 0, 0);
  146. rgb_led_.Dim(animation_counter_);
  147. break;
  148. case FEAT_MODE_SEQ_MAIN:
  149. channel_leds_.set_channel(0, 255); break;
  150. case FEAT_MODE_SEQ_SHIFT_REGISTER:
  151. channel_leds_.set_channel(1, 255); break;
  152. case FEAT_MODE_SEQ_STEP_EDIT:
  153. break;
  154. case FEAT_MODE_POLY_LFO:
  155. channel_leds_.set_channel(2, 255); break;
  156. case FEAT_MODE_EUCLIDEAN:
  157. channel_leds_.set_channel(3, 255); break;
  158. }
  159. break;
  160. case UI_MODE_SAVE_CONFIRMATION:
  161. animation_counter_ -= 256;
  162. if (active_slot_ == 0) {
  163. channel_leds_.set_channel(0, (animation_counter_ + 0) >> 8);
  164. channel_leds_.set_channel(1, (animation_counter_ + 16384) >> 8);
  165. channel_leds_.set_channel(2, (animation_counter_ + 32768) >> 8);
  166. channel_leds_.set_channel(3, (animation_counter_ + 49152) >> 8);
  167. } else {
  168. for (int i=0; i<4; i++)
  169. channel_leds_.set_channel(i, active_slot_ == i+1 ?
  170. animation_counter_ >> 8 : 0);
  171. }
  172. rgb_led_.set_color(0, 255, 0);
  173. break;
  174. case UI_MODE_ERASE_CONFIRMATION:
  175. animation_counter_ -= 256;
  176. if (active_slot_ == 0) {
  177. channel_leds_.set_channel(0, (animation_counter_ + 0) >> 8);
  178. channel_leds_.set_channel(1, (animation_counter_ + 16384) >> 8);
  179. channel_leds_.set_channel(2, (animation_counter_ + 32768) >> 8);
  180. channel_leds_.set_channel(3, (animation_counter_ + 49152) >> 8);
  181. } else {
  182. for (int i=0; i<4; i++)
  183. channel_leds_.set_channel(i, active_slot_ == i+1 ?
  184. animation_counter_ >> 8 : 0);
  185. }
  186. rgb_led_.set_color(255, 0, 0);
  187. break;
  188. case UI_MODE_FACTORY_TESTING:
  189. channel_leds_.set_channel(0, keyframer_->level(0) >> 8);
  190. channel_leds_.set_channel(1, keyframer_->level(1) >> 8);
  191. channel_leds_.set_channel(2, keyframer_->level(2) >> 8);
  192. channel_leds_.set_channel(3, keyframer_->level(3) >> 8);
  193. if (frame() < 4096) {
  194. rgb_led_.set_color(255, 0, 0);
  195. } else if (frame() > 61440) {
  196. rgb_led_.set_color(0, 255, 0);
  197. } else {
  198. uint8_t v = frame_modulation() >> 8;
  199. rgb_led_.set_color(0, 0, v);
  200. }
  201. if (test_led_) {
  202. keyframe_led_.High();
  203. } else {
  204. keyframe_led_.Low();
  205. }
  206. break;
  207. case UI_MODE_NORMAL:
  208. if (feature_mode_ == FEAT_MODE_POLY_LFO) {
  209. channel_leds_.set_channel(0, poly_lfo_->level(0));
  210. channel_leds_.set_channel(1, poly_lfo_->level(1));
  211. channel_leds_.set_channel(2, poly_lfo_->level(2));
  212. channel_leds_.set_channel(3, poly_lfo_->level(3));
  213. rgb_led_.set_color(poly_lfo_->color());
  214. if (poly_lfo_->level(0) > 128) {
  215. keyframe_led_.High();
  216. } else {
  217. keyframe_led_.Low();
  218. }
  219. } else if (feature_mode_ == FEAT_MODE_EUCLIDEAN) {
  220. channel_leds_.set_channel(0, euclidean_[0].level());
  221. channel_leds_.set_channel(1, euclidean_[1].level());
  222. channel_leds_.set_channel(2, euclidean_[2].level());
  223. channel_leds_.set_channel(3, euclidean_[3].level());
  224. } else if (feature_mode_ == FEAT_MODE_SEQ_STEP_EDIT) {
  225. channel_leds_.set_channel(0, keyframer_->level(0) >> 8);
  226. channel_leds_.set_channel(1, keyframer_->level(1) >> 8);
  227. channel_leds_.set_channel(2, keyframer_->level(2) >> 8);
  228. channel_leds_.set_channel(3, keyframer_->level(3) >> 8);
  229. rgb_led_.set_color(keyframer_->color());
  230. ++keyframe_led_pwm_counter_;
  231. if ((keyframe_led_pwm_counter_ & 15) >= 15) {
  232. keyframe_led_.High();
  233. } else {
  234. keyframe_led_.Low();
  235. }
  236. break;
  237. } else if (feature_mode_ == FEAT_MODE_SEQ_SHIFT_REGISTER) {
  238. channel_leds_.set_channel(0, shift_register[0] >> 8);
  239. channel_leds_.set_channel(1, shift_register[1] >> 8);
  240. channel_leds_.set_channel(2, shift_register[2] >> 8);
  241. channel_leds_.set_channel(3, shift_register[3] >> 8);
  242. rgb_led_.set_color(keyframer_->color());
  243. if (active_keyframe_ == -1) {
  244. keyframe_led_.Low();
  245. } else {
  246. animation_counter_ += 256;
  247. int32_t distance = frame() - \
  248. keyframer_->keyframe(active_keyframe_).timestamp;
  249. distance = min(distance * distance >> 18, int32_t(15));
  250. ++keyframe_led_pwm_counter_;
  251. if ((keyframe_led_pwm_counter_ & 15) >= distance) {
  252. keyframe_led_.High();
  253. } else {
  254. keyframe_led_.Low();
  255. }
  256. if (active_keyframe_lock_) {
  257. if (animation_counter_ & 0x8000) {
  258. keyframe_led_.High();
  259. } else {
  260. keyframe_led_.Low();
  261. }
  262. }
  263. }
  264. } else {
  265. channel_leds_.set_channel(0, keyframer_->level(0) >> 8);
  266. channel_leds_.set_channel(1, keyframer_->level(1) >> 8);
  267. channel_leds_.set_channel(2, keyframer_->level(2) >> 8);
  268. channel_leds_.set_channel(3, keyframer_->level(3) >> 8);
  269. rgb_led_.set_color(keyframer_->color());
  270. if (active_keyframe_ == -1) {
  271. keyframe_led_.Low();
  272. } else {
  273. animation_counter_ += 256;
  274. int32_t distance = frame() - \
  275. keyframer_->keyframe(active_keyframe_).timestamp;
  276. distance = min(distance * distance >> 18, int32_t(15));
  277. ++keyframe_led_pwm_counter_;
  278. if ((keyframe_led_pwm_counter_ & 15) >= distance) {
  279. keyframe_led_.High();
  280. } else {
  281. keyframe_led_.Low();
  282. }
  283. if (active_keyframe_lock_) {
  284. if (animation_counter_ & 0x8000) {
  285. keyframe_led_.High();
  286. } else {
  287. keyframe_led_.Low();
  288. }
  289. }
  290. }
  291. }
  292. break;
  293. case UI_MODE_EDIT_LENGTH:
  294. channel_leds_.set_channel(0, euclidean_[0].level());
  295. channel_leds_.set_channel(1, euclidean_[1].level());
  296. channel_leds_.set_channel(2, euclidean_[2].level());
  297. channel_leds_.set_channel(3, euclidean_[3].level());
  298. rgb_led_.set_color(255, 16, 32);
  299. break;
  300. case UI_MODE_EDIT_SHAPE:
  301. channel_leds_.set_channel(0, euclidean_[0].level());
  302. channel_leds_.set_channel(1, euclidean_[1].level());
  303. channel_leds_.set_channel(2, euclidean_[2].level());
  304. channel_leds_.set_channel(3, euclidean_[3].level());
  305. rgb_led_.set_color(16, 192, 32);
  306. break;
  307. case UI_MODE_EDIT_RESPONSE:
  308. case UI_MODE_EDIT_EASING:
  309. {
  310. animation_counter_ += 48;
  311. for (uint8_t i = 0; i < 4; ++i) {
  312. channel_leds_.set_channel(i, active_channel_ == i ? 255 : 0);
  313. }
  314. if (mode_ == UI_MODE_EDIT_EASING) {
  315. rgb_led_.set_color(255, 16, 32);
  316. } else {
  317. rgb_led_.set_color(16, 192, 32);
  318. }
  319. uint16_t brightness = active_channel_ == -1
  320. ? 65535
  321. : keyframer_->SampleAnimation(active_channel_,
  322. animation_counter_,
  323. mode_ == UI_MODE_EDIT_EASING);
  324. rgb_led_.Dim(brightness);
  325. }
  326. break;
  327. }
  328. rgb_led_.Write();
  329. channel_leds_.Write();
  330. }
  331. void Ui::FlushEvents() {
  332. queue_.Flush();
  333. }
  334. void Ui::OnSwitchPressed(const Event& e) {
  335. test_led_ = true;
  336. // double press -> feature switch mode
  337. if ((e.control_id == 0 && switches_.pressed_immediate(1)) ||
  338. (e.control_id == 1 && switches_.pressed_immediate(0))) {
  339. mode_ = UI_MODE_FEATURE_SWITCH;
  340. ignore_releases_ = 2;
  341. }
  342. }
  343. void Ui::OnSwitchReleased(const Event& e) {
  344. if (mode_ == UI_MODE_FACTORY_TESTING) {
  345. test_led_ = false;
  346. } else {
  347. if (active_keyframe_lock_) {
  348. active_keyframe_lock_ = false;
  349. FindNearestKeyframe();
  350. return;
  351. }
  352. // hack for double presses
  353. if (ignore_releases_ > 0) {
  354. ignore_releases_--;
  355. return;
  356. }
  357. switch (e.control_id) {
  358. case SWITCH_ADD_FRAME:
  359. if (e.data > kVeryLongPressDuration) {
  360. mode_ = UI_MODE_SAVE_CONFIRMATION;
  361. } else if (e.data > kLongPressDuration) {
  362. if (feature_mode_ == FEAT_MODE_KEYFRAMER ||
  363. feature_mode_ == FEAT_MODE_KEYFRAME_LOOPER) {
  364. mode_ = UI_MODE_EDIT_EASING;
  365. active_channel_ = -1;
  366. } else if (feature_mode_ == FEAT_MODE_EUCLIDEAN) {
  367. mode_ = UI_MODE_EDIT_LENGTH;
  368. } else if (feature_mode_ == FEAT_MODE_SEQ_MAIN) {
  369. keyframer_->Randomize();
  370. }
  371. } else {
  372. if (mode_ == UI_MODE_NORMAL &&
  373. (feature_mode_ == FEAT_MODE_KEYFRAMER ||
  374. feature_mode_ == FEAT_MODE_KEYFRAME_LOOPER ||
  375. feature_mode_ == FEAT_MODE_SEQ_MAIN ||
  376. feature_mode_ == FEAT_MODE_SEQ_SHIFT_REGISTER)) {
  377. if (active_keyframe_ == -1) {
  378. keyframer_->AddKeyframe(frame(), &adc_value_[0]);
  379. } else {
  380. // This abandoned feature allowed to select and continue editing
  381. // a keyframe with the 4 knobs on the top even when the big
  382. // frame knob is being played. For that, we select the keyframe
  383. // we are interested in, we press "add", and this "locks" the
  384. // 4 pots at the top of the module for editing this keyframe.
  385. //active_keyframe_lock_ = true;
  386. }
  387. FindNearestKeyframe();
  388. } else if (mode_ == UI_MODE_SAVE_CONFIRMATION) {
  389. // confirming save -> write to active slot
  390. keyframer_->feature_mode_ = feature_mode_;
  391. keyframer_->Save(active_slot_);
  392. mode_ = UI_MODE_SPLASH;
  393. } else if (mode_ == UI_MODE_FEATURE_SWITCH) {
  394. mode_ = UI_MODE_NORMAL;
  395. } else if (feature_mode_ == FEAT_MODE_POLY_LFO) {
  396. poly_lfo_->Reset();
  397. } else if (feature_mode_ == FEAT_MODE_SEQ_STEP_EDIT) {
  398. feature_mode_ = FEAT_MODE_SEQ_MAIN;
  399. } else {
  400. mode_ = UI_MODE_NORMAL;
  401. }
  402. }
  403. break;
  404. case SWITCH_DELETE_FRAME:
  405. if (e.data > kVeryLongPressDuration) {
  406. mode_ = UI_MODE_ERASE_CONFIRMATION;
  407. } else if (e.data > kLongPressDuration) {
  408. if (feature_mode_ == FEAT_MODE_SEQ_MAIN) {
  409. feature_mode_ = FEAT_MODE_SEQ_STEP_EDIT;
  410. } else if (feature_mode_ == FEAT_MODE_KEYFRAMER ||
  411. feature_mode_ == FEAT_MODE_KEYFRAME_LOOPER) {
  412. mode_ = UI_MODE_EDIT_RESPONSE;
  413. active_channel_ = -1;
  414. } else if (feature_mode_ == FEAT_MODE_EUCLIDEAN) {
  415. mode_ = UI_MODE_EDIT_SHAPE;
  416. }
  417. } else if (mode_ == UI_MODE_ERASE_CONFIRMATION) {
  418. if (active_slot_ == 0) {
  419. keyframer_->Clear();
  420. FindNearestKeyframe();
  421. SyncWithPots();
  422. feature_mode_ = FEAT_MODE_KEYFRAMER;
  423. } else {
  424. keyframer_->Load(active_slot_);
  425. feature_mode_ = static_cast<FeatureMode>(keyframer_->feature_mode_);
  426. for (int i=0; i<kNumChannels; i++) {
  427. euclidean_[i].set_length(keyframer_->euclidean_length_[i]);
  428. euclidean_[i].set_shape(keyframer_->euclidean_shape_[i]);
  429. }
  430. }
  431. mode_ = UI_MODE_SPLASH;
  432. } else {
  433. if (mode_ == UI_MODE_NORMAL &&
  434. (feature_mode_ == FEAT_MODE_KEYFRAMER ||
  435. feature_mode_ == FEAT_MODE_KEYFRAME_LOOPER ||
  436. feature_mode_ == FEAT_MODE_SEQ_MAIN ||
  437. feature_mode_ == FEAT_MODE_SEQ_SHIFT_REGISTER)) {
  438. if (active_keyframe_ != -1) {
  439. keyframer_->RemoveKeyframe(
  440. keyframer_->keyframe(active_keyframe_).timestamp);
  441. }
  442. FindNearestKeyframe();
  443. SyncWithPots();
  444. } else if (mode_ == UI_MODE_FEATURE_SWITCH) {
  445. mode_ = UI_MODE_NORMAL;
  446. } else if (feature_mode_ == FEAT_MODE_POLY_LFO) {
  447. poly_lfo_->Randomize();
  448. } else if (feature_mode_ == FEAT_MODE_SEQ_STEP_EDIT) {
  449. feature_mode_ = FEAT_MODE_SEQ_MAIN;
  450. } else {
  451. mode_ = UI_MODE_NORMAL;
  452. }
  453. }
  454. break;
  455. }
  456. }
  457. }
  458. void Ui::ParseShiftSequencer(uint16_t control_id, int32_t data) {
  459. // knob 1 is sequence order randomization, knobs 2 and 3
  460. // are divisors for the shift register, knob 4 randomizes
  461. // feedback value
  462. switch (control_id) {
  463. case 0:
  464. if (active_keyframe_ != -1) {
  465. Keyframe* k = keyframer_->mutable_keyframe(active_keyframe_);
  466. k->values[0] = data;
  467. } else {
  468. keyframer_->set_immediate(0, data);
  469. }
  470. break;
  471. case 1:
  472. if (data < 32768) {
  473. step_random = 0;
  474. step_divider = (((32768 - data) * kDividersSteps >> 15) + 1) % kDividersSteps;
  475. } else {
  476. int16_t rnd = data - 32768;
  477. rnd = (rnd * rnd) >> 15;
  478. step_random = rnd >> 7;
  479. step_divider = 1;
  480. }
  481. break;
  482. case 2:
  483. if (data < 32768) {
  484. shift_random = 0;
  485. shift_divider = (((32768 - data) * kDividersSteps >> 15) + 1) % kDividersSteps;
  486. } else {
  487. int16_t rnd = data - 32768;
  488. rnd = (rnd * rnd) >> 15;
  489. shift_random = rnd >> 7;
  490. shift_divider = 1;
  491. }
  492. break;
  493. case 3:
  494. if (data < 32768) {
  495. feedback_random = 0;
  496. int16_t rnd = 32768 - data;
  497. rnd = (rnd * rnd) >> 15;
  498. sequencer_random = rnd >> 7;
  499. } else {
  500. int16_t rnd = data - 32768;
  501. rnd = (rnd * rnd) >> 15;
  502. feedback_random = rnd >> 7;
  503. sequencer_random = 0;
  504. }
  505. break;
  506. feedback_random = data >> 8;
  507. break;
  508. case kFrameAdcChannel:
  509. if (!active_keyframe_lock_) {
  510. FindNearestKeyframe();
  511. }
  512. // big knob also sets number of registers
  513. active_registers = (data * kMaxRegisters >> 16) + 1;
  514. }
  515. }
  516. void Ui::ParsePolyLFO(uint16_t control_id, int32_t data) {
  517. switch (control_id) {
  518. case 0:
  519. poly_lfo_->set_shape(data);
  520. break;
  521. case 1:
  522. poly_lfo_->set_shape_spread(data);
  523. break;
  524. case 2:
  525. poly_lfo_->set_spread(data);
  526. break;
  527. case 3:
  528. poly_lfo_->set_coupling(data);
  529. break;
  530. }
  531. }
  532. void Ui::ParseEuclidean(uint16_t control_id, int32_t data) {
  533. if (mode_ == UI_MODE_EDIT_LENGTH) {
  534. switch (control_id) {
  535. case 0:
  536. case 1:
  537. case 2:
  538. case 3:
  539. {
  540. uint8_t len = (data >> 12) + 1;
  541. euclidean_[control_id].set_length(len);
  542. keyframer_->euclidean_length_[control_id] = len;
  543. }
  544. break;
  545. case kFrameAdcChannel:
  546. for (int i=0; i<kNumChannels; i++)
  547. euclidean_[i].set_rotate(data * i);
  548. break;
  549. }
  550. } else if (mode_ == UI_MODE_EDIT_SHAPE) {
  551. switch (control_id) {
  552. case 0:
  553. case 1:
  554. case 2:
  555. case 3:
  556. {
  557. euclidean_[control_id].set_shape(data);
  558. keyframer_->euclidean_shape_[control_id] = data;
  559. }
  560. break;
  561. case kFrameAdcChannel:
  562. for (int i=0; i<kNumChannels; i++)
  563. euclidean_[i].set_rotate(data * i);
  564. break;
  565. }
  566. } else {
  567. // normal mode or scratch or feature switch
  568. switch (control_id) {
  569. case 0:
  570. case 1:
  571. case 2:
  572. case 3:
  573. euclidean_[control_id].set_fill(data);
  574. break;
  575. case kFrameAdcChannel:
  576. for (int i=0; i<kNumChannels; i++)
  577. euclidean_[i].set_rotate(data * i);
  578. break;
  579. }
  580. }
  581. }
  582. void Ui::OnPotChanged(const Event& e) {
  583. if (mode_ == UI_MODE_FACTORY_TESTING) {
  584. switch (e.control_id) {
  585. case 0:
  586. case 1:
  587. case 2:
  588. case 3:
  589. keyframer_->set_immediate(e.control_id, e.data);
  590. break;
  591. }
  592. } else if (mode_ == UI_MODE_FEATURE_SWITCH) {
  593. switch (e.control_id) {
  594. case kFrameAdcChannel:
  595. feature_mode_ = e.data > 60000 ?
  596. FEAT_MODE_KEYFRAME_LOOPER :
  597. FEAT_MODE_KEYFRAMER;
  598. SyncWithPots();
  599. break;
  600. case 0:
  601. feature_mode_ = FEAT_MODE_SEQ_MAIN;
  602. SyncWithPots();
  603. break;
  604. case 1:
  605. feature_mode_ = FEAT_MODE_SEQ_SHIFT_REGISTER;
  606. SyncWithPotsShiftSequencer();
  607. break;
  608. case 2:
  609. feature_mode_ = FEAT_MODE_POLY_LFO;
  610. SyncWithPotsPolyLFO();
  611. break;
  612. case 3:
  613. feature_mode_ = FEAT_MODE_EUCLIDEAN;
  614. // TODO marche pas
  615. SyncWithPotsEuclidean();
  616. break;
  617. }
  618. } else if (mode_ == UI_MODE_SAVE_CONFIRMATION ||
  619. mode_ == UI_MODE_ERASE_CONFIRMATION) {
  620. switch (e.control_id) {
  621. case 0:
  622. case 1:
  623. case 2:
  624. case 3:
  625. active_slot_ = e.control_id + 1;
  626. break;
  627. case kFrameAdcChannel:
  628. active_slot_ = 0;
  629. }
  630. } else if (feature_mode_ == FEAT_MODE_POLY_LFO) {
  631. ParsePolyLFO(e.control_id, e.data);
  632. } else if (feature_mode_ == FEAT_MODE_SEQ_STEP_EDIT) {
  633. switch (e.control_id) {
  634. case 0:
  635. case 1:
  636. case 2:
  637. case 3:
  638. // the controls directly edit the value of the current step
  639. Keyframe* k = keyframer_->mutable_keyframe(sequencer_step);
  640. k->values[e.control_id] = e.data;
  641. }
  642. } else if (feature_mode_ == FEAT_MODE_EUCLIDEAN) {
  643. ParseEuclidean(e.control_id, e.data);
  644. } else if (feature_mode_ == FEAT_MODE_SEQ_SHIFT_REGISTER) {
  645. ParseShiftSequencer(e.control_id, e.data);
  646. } else {
  647. switch (e.control_id) {
  648. case 0:
  649. case 1:
  650. case 2:
  651. case 3:
  652. if (mode_ == UI_MODE_NORMAL || mode_ == UI_MODE_SPLASH) {
  653. if (active_keyframe_ != -1) {
  654. Keyframe* k = keyframer_->mutable_keyframe(active_keyframe_);
  655. k->values[e.control_id] = e.data;
  656. } else {
  657. keyframer_->set_immediate(e.control_id, e.data);
  658. }
  659. } else if (mode_ == UI_MODE_EDIT_RESPONSE) {
  660. active_channel_ = e.control_id;
  661. keyframer_->mutable_settings(e.control_id)->response = e.data >> 8;
  662. } else if (mode_ == UI_MODE_EDIT_EASING) {
  663. active_channel_ = e.control_id;
  664. keyframer_->mutable_settings(e.control_id)->easing_curve = \
  665. static_cast<EasingCurve>(e.data * 6 >> 16);
  666. }
  667. break;
  668. case kFrameAdcChannel:
  669. if (!active_keyframe_lock_) {
  670. FindNearestKeyframe();
  671. }
  672. break;
  673. case kFrameModulationAdcChannel:
  674. break;
  675. }
  676. }
  677. }
  678. void Ui::FindNearestKeyframe() {
  679. active_keyframe_ = keyframer_->FindNearestKeyframe(
  680. frame(),
  681. kKeyframeGridTolerance);
  682. }
  683. void Ui::SyncWithPots() {
  684. if (!keyframer_->num_keyframes()) {
  685. for (uint8_t i = 0; i < kNumChannels; ++i) {
  686. keyframer_->set_immediate(i, adc_filtered_value_[i]);
  687. }
  688. }
  689. }
  690. void Ui::SyncWithPotsShiftSequencer() {
  691. for (uint8_t i = 0; i < kNumChannels; ++i) {
  692. ParseShiftSequencer(i, adc_value_[i]);
  693. }
  694. }
  695. void Ui::SyncWithPotsEuclidean() {
  696. for (uint8_t i = 0; i < kNumChannels; ++i) {
  697. ParseEuclidean(i, adc_value_[i]);
  698. }
  699. }
  700. void Ui::SyncWithPotsPolyLFO() {
  701. for (uint8_t i = 0; i < kNumChannels; ++i) {
  702. ParsePolyLFO(i, adc_value_[i]);
  703. }
  704. }
  705. void Ui::DoEvents() {
  706. while (queue_.available()) {
  707. Event e = queue_.PullEvent();
  708. if (e.control_type == CONTROL_SWITCH) {
  709. if (e.data == 0) {
  710. OnSwitchPressed(e);
  711. } else {
  712. OnSwitchReleased(e);
  713. }
  714. } else if (e.control_type == CONTROL_POT) {
  715. OnPotChanged(e);
  716. }
  717. }
  718. if (queue_.idle_time() > 500) {
  719. queue_.Touch();
  720. if (mode_ == UI_MODE_SPLASH) {
  721. mode_ = UI_MODE_NORMAL;
  722. }
  723. }
  724. }
  725. } // namespace frames