|
- // Copyright 2013 Olivier Gillet.
- //
- // Author: Olivier Gillet (ol.gillet@gmail.com)
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- //
- // See http://creativecommons.org/licenses/MIT/ for more information.
- //
- // -----------------------------------------------------------------------------
- //
- // User interface.
-
- #include "frames/ui.h"
-
- #include <algorithm>
-
- #include "frames/keyframer.h"
- #include "frames/poly_lfo.h"
- #include "frames/euclidean.h"
-
- namespace frames {
-
- using namespace std;
- using namespace stmlib;
-
- const uint16_t kAdcThreshold = 1 << (16 - 10); // 10 bits
- const int32_t kLongPressDuration = 800;
- const int32_t kVeryLongPressDuration = 2000;
- const uint16_t kKeyframeGridTolerance = 2048;
- const uint8_t kDividersSteps = 7;
- const uint16_t kDeadZone = 2048; // 0..32767
-
- void Ui::Init(Keyframer* keyframer, PolyLfo* poly_lfo, Euclidean euclidean[kNumChannels]) {
- factory_testing_switch_.Init();
- channel_leds_.Init();
- keyframe_led_.Init();
- rgb_led_.Init();
- switches_.Init();
- adc_.Init(false);
-
- fill(&adc_value_[0], &adc_value_[kNumAdcChannels], 0);
-
- keyframer_ = keyframer;
- poly_lfo_ = poly_lfo;
- euclidean_ = euclidean;
- mode_ = factory_testing_switch_.Read()
- ? UI_MODE_SPLASH
- : UI_MODE_FACTORY_TESTING;
- animation_counter_ = 0;
- ignore_releases_ = 0;
- active_slot_ = 0;
-
- FindNearestKeyframe();
- active_keyframe_lock_ = false;
-
- feature_mode_ = static_cast<FeatureMode>(keyframer_->feature_mode_);
- for (int i=0; i<kNumChannels; i++) {
- euclidean_[i].set_length(keyframer_->euclidean_length_[i]);
- euclidean_[i].set_shape(keyframer_->euclidean_shape_[i]);
- }
-
- sequencer_step = 0;
- step_divider = 1;
- step_random = 0;
- shift_divider = 1;
- shift_random = 0;
- feedback_random = 0;
- active_registers = kMaxRegisters;
- for (int i=0; i<kMaxRegisters; i++)
- shift_register[i] = 0;
- }
-
- void Ui::TryCalibration() {
- if (switches_.pressed_immediate(1)) {
- keyframer_->Calibrate(frame_modulation());
- FlushEvents();
- }
- }
-
- void Ui::Poll() {
- switches_.Debounce();
-
- for (uint8_t i = 0; i < kNumSwitches; ++i) {
- if (switches_.just_pressed(i)) {
- queue_.AddEvent(CONTROL_SWITCH, i, 0);
- press_time_[i] = system_clock.milliseconds();
- detect_very_long_press_[i] = false;
- }
- if (switches_.pressed(i)) {
- int32_t pressed_time = system_clock.milliseconds() - press_time_[i];
-
- if (!detect_very_long_press_[i]) {
- if (pressed_time > kLongPressDuration) {
- queue_.AddEvent(CONTROL_SWITCH, i, pressed_time);
- detect_very_long_press_[i] = true;
- }
- } else {
- if (pressed_time > kVeryLongPressDuration) {
- queue_.AddEvent(CONTROL_SWITCH, i, pressed_time);
- detect_very_long_press_[i] = false;
- press_time_[i] = 0;
- }
- }
- }
-
- if (switches_.released(i) &&
- press_time_[i] != 0 &&
- !detect_very_long_press_[i]) {
- queue_.AddEvent(
- CONTROL_SWITCH,
- i,
- system_clock.milliseconds() - press_time_[i] + 1);
- press_time_[i] = 0;
- detect_very_long_press_[i] = false;
- }
- }
-
- for (uint8_t i = 0; i <= kFrameAdcChannel; ++i) {
- int32_t value = (31 * adc_filtered_value_[i] + adc_.value(i)) >> 5;
- adc_filtered_value_[i] = value;
- int32_t current_value = static_cast<int32_t>(adc_value_[i]);
- if (value >= current_value + kAdcThreshold ||
- value <= current_value - kAdcThreshold) {
- queue_.AddEvent(CONTROL_POT, i, value);
- adc_value_[i] = value;
- }
- }
-
- switch (mode_) {
- case UI_MODE_SPLASH:
- animation_counter_ += 128;
- channel_leds_.set_channel(0, (animation_counter_ + 49152) >> 8);
- channel_leds_.set_channel(1, (animation_counter_ + 32768) >> 8);
- channel_leds_.set_channel(2, (animation_counter_ + 16384) >> 8);
- channel_leds_.set_channel(3, (animation_counter_ + 0) >> 8);
- rgb_led_.set_color(255, 255, 255);
- break;
-
- case UI_MODE_FEATURE_SWITCH:
- animation_counter_ += 1024;
- rgb_led_.set_color(255, 255, 255);
- rgb_led_.Dim(animation_counter_);
-
- for (int i=0; i<4; i++)
- channel_leds_.set_channel(i, 0);
-
- switch (feature_mode_) {
- case FEAT_MODE_KEYFRAMER:
- break;
- case FEAT_MODE_KEYFRAME_LOOPER:
- rgb_led_.set_color(255, 0, 0);
- rgb_led_.Dim(animation_counter_);
- break;
- case FEAT_MODE_SEQ_MAIN:
- channel_leds_.set_channel(0, 255); break;
- case FEAT_MODE_SEQ_SHIFT_REGISTER:
- channel_leds_.set_channel(1, 255); break;
- case FEAT_MODE_SEQ_STEP_EDIT:
- break;
- case FEAT_MODE_POLY_LFO:
- channel_leds_.set_channel(2, 255); break;
- case FEAT_MODE_EUCLIDEAN:
- channel_leds_.set_channel(3, 255); break;
- }
-
- break;
-
- case UI_MODE_SAVE_CONFIRMATION:
- animation_counter_ -= 256;
- if (active_slot_ == 0) {
- channel_leds_.set_channel(0, (animation_counter_ + 0) >> 8);
- channel_leds_.set_channel(1, (animation_counter_ + 16384) >> 8);
- channel_leds_.set_channel(2, (animation_counter_ + 32768) >> 8);
- channel_leds_.set_channel(3, (animation_counter_ + 49152) >> 8);
- } else {
- for (int i=0; i<4; i++)
- channel_leds_.set_channel(i, active_slot_ == i+1 ?
- animation_counter_ >> 8 : 0);
- }
- rgb_led_.set_color(0, 255, 0);
- break;
-
- case UI_MODE_ERASE_CONFIRMATION:
- animation_counter_ -= 256;
- if (active_slot_ == 0) {
- channel_leds_.set_channel(0, (animation_counter_ + 0) >> 8);
- channel_leds_.set_channel(1, (animation_counter_ + 16384) >> 8);
- channel_leds_.set_channel(2, (animation_counter_ + 32768) >> 8);
- channel_leds_.set_channel(3, (animation_counter_ + 49152) >> 8);
- } else {
- for (int i=0; i<4; i++)
- channel_leds_.set_channel(i, active_slot_ == i+1 ?
- animation_counter_ >> 8 : 0);
- }
- rgb_led_.set_color(255, 0, 0);
- break;
-
- case UI_MODE_FACTORY_TESTING:
- channel_leds_.set_channel(0, keyframer_->level(0) >> 8);
- channel_leds_.set_channel(1, keyframer_->level(1) >> 8);
- channel_leds_.set_channel(2, keyframer_->level(2) >> 8);
- channel_leds_.set_channel(3, keyframer_->level(3) >> 8);
- if (frame() < 4096) {
- rgb_led_.set_color(255, 0, 0);
- } else if (frame() > 61440) {
- rgb_led_.set_color(0, 255, 0);
- } else {
- uint8_t v = frame_modulation() >> 8;
- rgb_led_.set_color(0, 0, v);
- }
- if (test_led_) {
- keyframe_led_.High();
- } else {
- keyframe_led_.Low();
- }
- break;
-
- case UI_MODE_NORMAL:
-
- if (feature_mode_ == FEAT_MODE_POLY_LFO) {
- channel_leds_.set_channel(0, poly_lfo_->level(0));
- channel_leds_.set_channel(1, poly_lfo_->level(1));
- channel_leds_.set_channel(2, poly_lfo_->level(2));
- channel_leds_.set_channel(3, poly_lfo_->level(3));
- rgb_led_.set_color(poly_lfo_->color());
- if (poly_lfo_->level(0) > 128) {
- keyframe_led_.High();
- } else {
- keyframe_led_.Low();
- }
- } else if (feature_mode_ == FEAT_MODE_EUCLIDEAN) {
- channel_leds_.set_channel(0, euclidean_[0].level());
- channel_leds_.set_channel(1, euclidean_[1].level());
- channel_leds_.set_channel(2, euclidean_[2].level());
- channel_leds_.set_channel(3, euclidean_[3].level());
- } else if (feature_mode_ == FEAT_MODE_SEQ_STEP_EDIT) {
- channel_leds_.set_channel(0, keyframer_->level(0) >> 8);
- channel_leds_.set_channel(1, keyframer_->level(1) >> 8);
- channel_leds_.set_channel(2, keyframer_->level(2) >> 8);
- channel_leds_.set_channel(3, keyframer_->level(3) >> 8);
- rgb_led_.set_color(keyframer_->color());
-
- ++keyframe_led_pwm_counter_;
- if ((keyframe_led_pwm_counter_ & 15) >= 15) {
- keyframe_led_.High();
- } else {
- keyframe_led_.Low();
- }
- break;
- } else if (feature_mode_ == FEAT_MODE_SEQ_SHIFT_REGISTER) {
- channel_leds_.set_channel(0, shift_register[0] >> 8);
- channel_leds_.set_channel(1, shift_register[1] >> 8);
- channel_leds_.set_channel(2, shift_register[2] >> 8);
- channel_leds_.set_channel(3, shift_register[3] >> 8);
- rgb_led_.set_color(keyframer_->color());
-
- if (active_keyframe_ == -1) {
- keyframe_led_.Low();
- } else {
- animation_counter_ += 256;
- int32_t distance = frame() - \
- keyframer_->keyframe(active_keyframe_).timestamp;
- distance = min(distance * distance >> 18, int32_t(15));
- ++keyframe_led_pwm_counter_;
- if ((keyframe_led_pwm_counter_ & 15) >= distance) {
- keyframe_led_.High();
- } else {
- keyframe_led_.Low();
- }
- if (active_keyframe_lock_) {
- if (animation_counter_ & 0x8000) {
- keyframe_led_.High();
- } else {
- keyframe_led_.Low();
- }
- }
- }
- } else {
- channel_leds_.set_channel(0, keyframer_->level(0) >> 8);
- channel_leds_.set_channel(1, keyframer_->level(1) >> 8);
- channel_leds_.set_channel(2, keyframer_->level(2) >> 8);
- channel_leds_.set_channel(3, keyframer_->level(3) >> 8);
- rgb_led_.set_color(keyframer_->color());
- if (active_keyframe_ == -1) {
- keyframe_led_.Low();
- } else {
- animation_counter_ += 256;
- int32_t distance = frame() - \
- keyframer_->keyframe(active_keyframe_).timestamp;
- distance = min(distance * distance >> 18, int32_t(15));
- ++keyframe_led_pwm_counter_;
- if ((keyframe_led_pwm_counter_ & 15) >= distance) {
- keyframe_led_.High();
- } else {
- keyframe_led_.Low();
- }
- if (active_keyframe_lock_) {
- if (animation_counter_ & 0x8000) {
- keyframe_led_.High();
- } else {
- keyframe_led_.Low();
- }
- }
- }
- }
- break;
-
- case UI_MODE_EDIT_LENGTH:
- channel_leds_.set_channel(0, euclidean_[0].level());
- channel_leds_.set_channel(1, euclidean_[1].level());
- channel_leds_.set_channel(2, euclidean_[2].level());
- channel_leds_.set_channel(3, euclidean_[3].level());
- rgb_led_.set_color(255, 16, 32);
- break;
- case UI_MODE_EDIT_SHAPE:
- channel_leds_.set_channel(0, euclidean_[0].level());
- channel_leds_.set_channel(1, euclidean_[1].level());
- channel_leds_.set_channel(2, euclidean_[2].level());
- channel_leds_.set_channel(3, euclidean_[3].level());
- rgb_led_.set_color(16, 192, 32);
- break;
-
- case UI_MODE_EDIT_RESPONSE:
- case UI_MODE_EDIT_EASING:
- {
- animation_counter_ += 48;
- for (uint8_t i = 0; i < 4; ++i) {
- channel_leds_.set_channel(i, active_channel_ == i ? 255 : 0);
- }
- if (mode_ == UI_MODE_EDIT_EASING) {
- rgb_led_.set_color(255, 16, 32);
- } else {
- rgb_led_.set_color(16, 192, 32);
- }
- uint16_t brightness = active_channel_ == -1
- ? 65535
- : keyframer_->SampleAnimation(active_channel_,
- animation_counter_,
- mode_ == UI_MODE_EDIT_EASING);
- rgb_led_.Dim(brightness);
- }
- break;
- }
-
- rgb_led_.Write();
- channel_leds_.Write();
- }
-
- void Ui::FlushEvents() {
- queue_.Flush();
- }
-
- void Ui::OnSwitchPressed(const Event& e) {
- test_led_ = true;
-
- // double press -> feature switch mode
- if ((e.control_id == 0 && switches_.pressed_immediate(1)) ||
- (e.control_id == 1 && switches_.pressed_immediate(0))) {
- mode_ = UI_MODE_FEATURE_SWITCH;
- ignore_releases_ = 2;
- }
- }
-
- void Ui::OnSwitchReleased(const Event& e) {
- if (mode_ == UI_MODE_FACTORY_TESTING) {
- test_led_ = false;
- } else {
- if (active_keyframe_lock_) {
- active_keyframe_lock_ = false;
- FindNearestKeyframe();
- return;
- }
-
- // hack for double presses
- if (ignore_releases_ > 0) {
- ignore_releases_--;
- return;
- }
-
- switch (e.control_id) {
- case SWITCH_ADD_FRAME:
- if (e.data > kVeryLongPressDuration) {
- mode_ = UI_MODE_SAVE_CONFIRMATION;
- } else if (e.data > kLongPressDuration) {
- if (feature_mode_ == FEAT_MODE_KEYFRAMER ||
- feature_mode_ == FEAT_MODE_KEYFRAME_LOOPER) {
- mode_ = UI_MODE_EDIT_EASING;
- active_channel_ = -1;
- } else if (feature_mode_ == FEAT_MODE_EUCLIDEAN) {
- mode_ = UI_MODE_EDIT_LENGTH;
- } else if (feature_mode_ == FEAT_MODE_SEQ_MAIN) {
- keyframer_->Randomize();
- }
- } else {
- if (mode_ == UI_MODE_NORMAL &&
- (feature_mode_ == FEAT_MODE_KEYFRAMER ||
- feature_mode_ == FEAT_MODE_KEYFRAME_LOOPER ||
- feature_mode_ == FEAT_MODE_SEQ_MAIN ||
- feature_mode_ == FEAT_MODE_SEQ_SHIFT_REGISTER)) {
- if (active_keyframe_ == -1) {
- keyframer_->AddKeyframe(frame(), &adc_value_[0]);
- } else {
- // This abandoned feature allowed to select and continue editing
- // a keyframe with the 4 knobs on the top even when the big
- // frame knob is being played. For that, we select the keyframe
- // we are interested in, we press "add", and this "locks" the
- // 4 pots at the top of the module for editing this keyframe.
- //active_keyframe_lock_ = true;
- }
- FindNearestKeyframe();
- } else if (mode_ == UI_MODE_SAVE_CONFIRMATION) {
- // confirming save -> write to active slot
- keyframer_->feature_mode_ = feature_mode_;
- keyframer_->Save(active_slot_);
- mode_ = UI_MODE_SPLASH;
- } else if (mode_ == UI_MODE_FEATURE_SWITCH) {
- mode_ = UI_MODE_NORMAL;
- } else if (feature_mode_ == FEAT_MODE_POLY_LFO) {
- poly_lfo_->Reset();
- } else if (feature_mode_ == FEAT_MODE_SEQ_STEP_EDIT) {
- feature_mode_ = FEAT_MODE_SEQ_MAIN;
- } else {
- mode_ = UI_MODE_NORMAL;
- }
- }
- break;
-
- case SWITCH_DELETE_FRAME:
- if (e.data > kVeryLongPressDuration) {
- mode_ = UI_MODE_ERASE_CONFIRMATION;
- } else if (e.data > kLongPressDuration) {
- if (feature_mode_ == FEAT_MODE_SEQ_MAIN) {
- feature_mode_ = FEAT_MODE_SEQ_STEP_EDIT;
- } else if (feature_mode_ == FEAT_MODE_KEYFRAMER ||
- feature_mode_ == FEAT_MODE_KEYFRAME_LOOPER) {
- mode_ = UI_MODE_EDIT_RESPONSE;
- active_channel_ = -1;
- } else if (feature_mode_ == FEAT_MODE_EUCLIDEAN) {
- mode_ = UI_MODE_EDIT_SHAPE;
- }
- } else if (mode_ == UI_MODE_ERASE_CONFIRMATION) {
- if (active_slot_ == 0) {
- keyframer_->Clear();
- FindNearestKeyframe();
- SyncWithPots();
- feature_mode_ = FEAT_MODE_KEYFRAMER;
- } else {
- keyframer_->Load(active_slot_);
- feature_mode_ = static_cast<FeatureMode>(keyframer_->feature_mode_);
- for (int i=0; i<kNumChannels; i++) {
- euclidean_[i].set_length(keyframer_->euclidean_length_[i]);
- euclidean_[i].set_shape(keyframer_->euclidean_shape_[i]);
- }
- }
- mode_ = UI_MODE_SPLASH;
- } else {
- if (mode_ == UI_MODE_NORMAL &&
- (feature_mode_ == FEAT_MODE_KEYFRAMER ||
- feature_mode_ == FEAT_MODE_KEYFRAME_LOOPER ||
- feature_mode_ == FEAT_MODE_SEQ_MAIN ||
- feature_mode_ == FEAT_MODE_SEQ_SHIFT_REGISTER)) {
- if (active_keyframe_ != -1) {
- keyframer_->RemoveKeyframe(
- keyframer_->keyframe(active_keyframe_).timestamp);
- }
- FindNearestKeyframe();
- SyncWithPots();
- } else if (mode_ == UI_MODE_FEATURE_SWITCH) {
- mode_ = UI_MODE_NORMAL;
- } else if (feature_mode_ == FEAT_MODE_POLY_LFO) {
- poly_lfo_->Randomize();
- } else if (feature_mode_ == FEAT_MODE_SEQ_STEP_EDIT) {
- feature_mode_ = FEAT_MODE_SEQ_MAIN;
- } else {
- mode_ = UI_MODE_NORMAL;
- }
- }
- break;
- }
- }
- }
-
- void Ui::ParseShiftSequencer(uint16_t control_id, int32_t data) {
- // knob 1 is sequence order randomization, knobs 2 and 3
- // are divisors for the shift register, knob 4 randomizes
- // feedback value
- switch (control_id) {
- case 0:
- if (active_keyframe_ != -1) {
- Keyframe* k = keyframer_->mutable_keyframe(active_keyframe_);
- k->values[0] = data;
- } else {
- keyframer_->set_immediate(0, data);
- }
- break;
- case 1:
- if (data < 32768) {
- step_random = 0;
- step_divider = (((32768 - data) * kDividersSteps >> 15) + 1) % kDividersSteps;
- } else {
- int16_t rnd = data - 32768;
- rnd = (rnd * rnd) >> 15;
- step_random = rnd >> 7;
- step_divider = 1;
- }
- break;
- case 2:
- if (data < 32768) {
- shift_random = 0;
- shift_divider = (((32768 - data) * kDividersSteps >> 15) + 1) % kDividersSteps;
- } else {
- int16_t rnd = data - 32768;
- rnd = (rnd * rnd) >> 15;
- shift_random = rnd >> 7;
- shift_divider = 1;
- }
- break;
- case 3:
- if (data < 32768) {
- feedback_random = 0;
- int16_t rnd = 32768 - data;
- rnd = (rnd * rnd) >> 15;
- sequencer_random = rnd >> 7;
- } else {
- int16_t rnd = data - 32768;
- rnd = (rnd * rnd) >> 15;
- feedback_random = rnd >> 7;
- sequencer_random = 0;
- }
- break;
- feedback_random = data >> 8;
- break;
- case kFrameAdcChannel:
- if (!active_keyframe_lock_) {
- FindNearestKeyframe();
- }
- // big knob also sets number of registers
- active_registers = (data * kMaxRegisters >> 16) + 1;
- }
- }
-
-
- void Ui::ParsePolyLFO(uint16_t control_id, int32_t data) {
- switch (control_id) {
- case 0:
- poly_lfo_->set_shape(data);
- break;
- case 1:
- poly_lfo_->set_shape_spread(data);
- break;
- case 2:
- poly_lfo_->set_spread(data);
- break;
- case 3:
- poly_lfo_->set_coupling(data);
- break;
- }
- }
-
- void Ui::ParseEuclidean(uint16_t control_id, int32_t data) {
- if (mode_ == UI_MODE_EDIT_LENGTH) {
- switch (control_id) {
- case 0:
- case 1:
- case 2:
- case 3:
- {
- uint8_t len = (data >> 12) + 1;
- euclidean_[control_id].set_length(len);
- keyframer_->euclidean_length_[control_id] = len;
- }
- break;
- case kFrameAdcChannel:
- for (int i=0; i<kNumChannels; i++)
- euclidean_[i].set_rotate(data * i);
- break;
- }
- } else if (mode_ == UI_MODE_EDIT_SHAPE) {
- switch (control_id) {
- case 0:
- case 1:
- case 2:
- case 3:
- {
- euclidean_[control_id].set_shape(data);
- keyframer_->euclidean_shape_[control_id] = data;
- }
- break;
- case kFrameAdcChannel:
- for (int i=0; i<kNumChannels; i++)
- euclidean_[i].set_rotate(data * i);
- break;
- }
- } else {
- // normal mode or scratch or feature switch
- switch (control_id) {
- case 0:
- case 1:
- case 2:
- case 3:
- euclidean_[control_id].set_fill(data);
- break;
- case kFrameAdcChannel:
- for (int i=0; i<kNumChannels; i++)
- euclidean_[i].set_rotate(data * i);
- break;
- }
- }
- }
-
- void Ui::OnPotChanged(const Event& e) {
- if (mode_ == UI_MODE_FACTORY_TESTING) {
- switch (e.control_id) {
- case 0:
- case 1:
- case 2:
- case 3:
- keyframer_->set_immediate(e.control_id, e.data);
- break;
- }
- } else if (mode_ == UI_MODE_FEATURE_SWITCH) {
- switch (e.control_id) {
- case kFrameAdcChannel:
- feature_mode_ = e.data > 60000 ?
- FEAT_MODE_KEYFRAME_LOOPER :
- FEAT_MODE_KEYFRAMER;
- SyncWithPots();
- break;
- case 0:
- feature_mode_ = FEAT_MODE_SEQ_MAIN;
- SyncWithPots();
- break;
- case 1:
- feature_mode_ = FEAT_MODE_SEQ_SHIFT_REGISTER;
- SyncWithPotsShiftSequencer();
- break;
- case 2:
- feature_mode_ = FEAT_MODE_POLY_LFO;
- SyncWithPotsPolyLFO();
- break;
- case 3:
- feature_mode_ = FEAT_MODE_EUCLIDEAN;
- // TODO marche pas
- SyncWithPotsEuclidean();
- break;
- }
- } else if (mode_ == UI_MODE_SAVE_CONFIRMATION ||
- mode_ == UI_MODE_ERASE_CONFIRMATION) {
- switch (e.control_id) {
- case 0:
- case 1:
- case 2:
- case 3:
- active_slot_ = e.control_id + 1;
- break;
- case kFrameAdcChannel:
- active_slot_ = 0;
- }
- } else if (feature_mode_ == FEAT_MODE_POLY_LFO) {
- ParsePolyLFO(e.control_id, e.data);
- } else if (feature_mode_ == FEAT_MODE_SEQ_STEP_EDIT) {
- switch (e.control_id) {
- case 0:
- case 1:
- case 2:
- case 3:
- // the controls directly edit the value of the current step
- Keyframe* k = keyframer_->mutable_keyframe(sequencer_step);
- k->values[e.control_id] = e.data;
- }
-
- } else if (feature_mode_ == FEAT_MODE_EUCLIDEAN) {
- ParseEuclidean(e.control_id, e.data);
-
- } else if (feature_mode_ == FEAT_MODE_SEQ_SHIFT_REGISTER) {
- ParseShiftSequencer(e.control_id, e.data);
- } else {
- switch (e.control_id) {
- case 0:
- case 1:
- case 2:
- case 3:
- if (mode_ == UI_MODE_NORMAL || mode_ == UI_MODE_SPLASH) {
- if (active_keyframe_ != -1) {
- Keyframe* k = keyframer_->mutable_keyframe(active_keyframe_);
- k->values[e.control_id] = e.data;
- } else {
- keyframer_->set_immediate(e.control_id, e.data);
- }
- } else if (mode_ == UI_MODE_EDIT_RESPONSE) {
- active_channel_ = e.control_id;
- keyframer_->mutable_settings(e.control_id)->response = e.data >> 8;
- } else if (mode_ == UI_MODE_EDIT_EASING) {
- active_channel_ = e.control_id;
- keyframer_->mutable_settings(e.control_id)->easing_curve = \
- static_cast<EasingCurve>(e.data * 6 >> 16);
- }
- break;
- case kFrameAdcChannel:
- if (!active_keyframe_lock_) {
- FindNearestKeyframe();
- }
- break;
- case kFrameModulationAdcChannel:
- break;
- }
- }
- }
-
- void Ui::FindNearestKeyframe() {
- active_keyframe_ = keyframer_->FindNearestKeyframe(
- frame(),
- kKeyframeGridTolerance);
- }
-
- void Ui::SyncWithPots() {
- if (!keyframer_->num_keyframes()) {
- for (uint8_t i = 0; i < kNumChannels; ++i) {
- keyframer_->set_immediate(i, adc_filtered_value_[i]);
- }
- }
- }
-
- void Ui::SyncWithPotsShiftSequencer() {
- for (uint8_t i = 0; i < kNumChannels; ++i) {
- ParseShiftSequencer(i, adc_value_[i]);
- }
- }
-
- void Ui::SyncWithPotsEuclidean() {
- for (uint8_t i = 0; i < kNumChannels; ++i) {
- ParseEuclidean(i, adc_value_[i]);
- }
- }
-
- void Ui::SyncWithPotsPolyLFO() {
- for (uint8_t i = 0; i < kNumChannels; ++i) {
- ParsePolyLFO(i, adc_value_[i]);
- }
- }
-
- void Ui::DoEvents() {
- while (queue_.available()) {
- Event e = queue_.PullEvent();
- if (e.control_type == CONTROL_SWITCH) {
- if (e.data == 0) {
- OnSwitchPressed(e);
- } else {
- OnSwitchReleased(e);
- }
- } else if (e.control_type == CONTROL_POT) {
- OnPotChanged(e);
- }
- }
- if (queue_.idle_time() > 500) {
- queue_.Touch();
- if (mode_ == UI_MODE_SPLASH) {
- mode_ = UI_MODE_NORMAL;
- }
- }
- }
-
- } // namespace frames
|