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 // Settings
28 
29 #ifndef FRAMES_UI_H_
30 #define FRAMES_UI_H_
31 
32 #include "stmlib/stmlib.h"
33 
34 #include "stmlib/ui/event_queue.h"
35 
36 #include "frames/drivers/adc.h"
37 #include "frames/drivers/channel_leds.h"
38 #include "frames/drivers/factory_testing_switch.h"
39 #include "frames/drivers/keyframe_led.h"
40 #include "frames/drivers/rgb_led.h"
41 #include "frames/drivers/switches.h"
42 
43 namespace frames {
44 
45 class Keyframer;
46 class PolyLfo;
47 class Euclidean;
48 
49 const uint8_t kMaxRegisters = 16;
50 
51 enum SwitchIndex {
52   SWITCH_ADD_FRAME,
53   SWITCH_DELETE_FRAME
54 };
55 
56 enum UiMode {
57   UI_MODE_SPLASH,
58   UI_MODE_FEATURE_SWITCH,
59   UI_MODE_NORMAL,
60   UI_MODE_SAVE_CONFIRMATION,
61   UI_MODE_ERASE_CONFIRMATION,
62   UI_MODE_EDIT_RESPONSE,
63   UI_MODE_EDIT_EASING,
64   UI_MODE_FACTORY_TESTING,
65   UI_MODE_EDIT_LENGTH,
66   UI_MODE_EDIT_SHAPE,
67 };
68 
69 class Ui {
70  public:
Ui()71   Ui() { }
~Ui()72   ~Ui() { }
73 
74   void Init(Keyframer* keyframer, PolyLfo* poly_lfo, Euclidean euclidean[kNumChannels]);
75   void Poll();
76   void DoEvents();
77   void FlushEvents();
78   void TryCalibration();
79 
frame()80   inline uint16_t frame() const {
81     return adc_.value(kFrameAdcChannel);
82   }
83 
frame_modulation()84   inline uint16_t frame_modulation() const {
85     return adc_.value(kFrameModulationAdcChannel);
86   }
87 
mode()88   inline UiMode mode() const {
89     return mode_;
90   }
91 
92   enum FeatureMode {
93     FEAT_MODE_KEYFRAMER,
94     FEAT_MODE_KEYFRAME_LOOPER,
95     FEAT_MODE_SEQ_MAIN,
96     FEAT_MODE_SEQ_SHIFT_REGISTER,
97     FEAT_MODE_SEQ_STEP_EDIT,
98     FEAT_MODE_POLY_LFO,
99     FEAT_MODE_EUCLIDEAN,
100   };
101 
feature_mode()102   inline FeatureMode feature_mode() const {
103     return feature_mode_;
104   }
105 
106   uint8_t sequencer_step;
107   uint8_t sequencer_random;
108   uint8_t step_divider;
109   uint8_t shift_divider;
110   uint8_t step_random;
111   uint8_t shift_random;
112   uint8_t feedback_random;
113   uint16_t shift_register[kMaxRegisters];
114   uint8_t active_registers;
115 
116   KeyframeLed keyframe_led_;
117   RgbLed rgb_led_;
118 
119  private:
120   void OnSwitchPressed(const stmlib::Event& e);
121   void OnSwitchReleased(const stmlib::Event& e);
122   void OnPotChanged(const stmlib::Event& e);
123   void ParseShiftSequencer(uint16_t control_id, int32_t data);
124   void ParsePolyLFO(uint16_t control_id, int32_t data);
125   void ParseEuclidean(uint16_t control_id, int32_t data);
126 
127   // Force the gain value of the 4 channels to match that of the 4 pots.
128   void SyncWithPots();
129   void SyncWithPotsShiftSequencer();
130   void SyncWithPotsPolyLFO();
131   void SyncWithPotsEuclidean();
132 
133   void FindNearestKeyframe();
134 
135   stmlib::EventQueue<32> queue_;
136 
137   uint16_t adc_value_[kNumAdcChannels];
138   uint16_t adc_filtered_value_[kNumAdcChannels];
139   uint32_t press_time_[kNumSwitches];
140   bool detect_very_long_press_[kNumSwitches];
141 
142   ChannelLeds channel_leds_;
143   Switches switches_;
144   Adc adc_;
145   FactoryTestingSwitch factory_testing_switch_;
146 
147   UiMode mode_;
148 
149   Keyframer* keyframer_;
150   PolyLfo* poly_lfo_;
151   Euclidean* euclidean_;
152 
153   int16_t active_keyframe_;
154   int16_t active_channel_;
155   int16_t active_slot_;
156   bool active_keyframe_lock_;
157 
158   FeatureMode feature_mode_;
159 
160   uint16_t animation_counter_;
161   uint16_t keyframe_led_pwm_counter_;
162 
163   uint8_t ignore_releases_;
164 
165   bool test_led_;
166 
167   DISALLOW_COPY_AND_ASSIGN(Ui);
168 };
169 
170 }  // namespace frames
171 
172 #endif  // FRAMES_UI_H_
173