Improved menu status display
Added ability to adjust key params from status and load preset
This commit is contained in:
parent
7219872a14
commit
a2f2fb260d
5 changed files with 165 additions and 84 deletions
|
@ -145,7 +145,7 @@ int readKnob(uint8_t n) {
|
|||
lastOut = out;
|
||||
|
||||
if (time - lastOutTime < KNOB_CURVE_THRESHOLD) {
|
||||
out *= constrain(KNOB_CURVE_THRESHOLD / time - lastOutTime, 1, KNOB_CURVE_MAX_MULTIPLIER);
|
||||
out *= constrain(KNOB_CURVE_THRESHOLD / (time - lastOutTime), 1, KNOB_CURVE_MAX_MULTIPLIER);
|
||||
}
|
||||
lastOutTime = time;
|
||||
}
|
||||
|
|
|
@ -3,25 +3,19 @@
|
|||
|
||||
void checkICM(state_t &state) {
|
||||
icm_result_t icmSignal = readICM();
|
||||
/*
|
||||
Serial.print(">roll: ");
|
||||
Serial.println(icmSignal.roll);
|
||||
Serial.print(">tilt: ");
|
||||
Serial.println(icmSignal.tilt);
|
||||
*/
|
||||
byte roll = mapConstrain(abs(icmSignal.roll), 0, 40, 127, 0);
|
||||
if (ExtraControl::CC == state.currentPreset->icmRollMode) {
|
||||
byte roll = mapConstrain(abs(icmSignal.roll), 0, 40, 127, 0);
|
||||
if (roll != state.instrument->rollCCVal) {
|
||||
midiSendControlChange(state.currentPreset->icmRollCC, roll);
|
||||
state.instrument->rollCCVal = roll;
|
||||
}
|
||||
}
|
||||
state.instrument->rollCCVal = roll;
|
||||
|
||||
byte tilt = mapConstrain(abs(icmSignal.tilt), -20, 40, 0, 127);
|
||||
if (ExtraControl::CC == state.currentPreset->icmTiltMode) {
|
||||
byte tilt = mapConstrain(abs(icmSignal.tilt), -20, 40, 0, 127);
|
||||
if (tilt != state.instrument->tiltCCVal) {
|
||||
midiSendControlChange(state.currentPreset->icmTiltCC, tilt);
|
||||
state.instrument->tiltCCVal = tilt;
|
||||
}
|
||||
}
|
||||
state.instrument->tiltCCVal = tilt;
|
||||
}
|
|
@ -295,8 +295,8 @@ static void drawAdjustValues(state_t& state, const AdjustValue& value, AdjustDra
|
|||
maxV += zero;
|
||||
}
|
||||
|
||||
char buffer[16];
|
||||
snprintf(buffer, 16, "%d>%d<%d", thrV, state.instrument->*value.value, maxV);
|
||||
char buffer[21];
|
||||
snprintf(buffer, 21, "% 5d>% 5d<% 5d", thrV, state.instrument->*value.value, maxV);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(128 - 6 * strlen(buffer), drawing.row - 9);
|
||||
display.println(buffer);
|
||||
|
@ -458,6 +458,10 @@ public:
|
|||
redraw = true;
|
||||
}
|
||||
|
||||
if (input.changed && (input.btnVal1 || input.btnVal2)) {
|
||||
displayOff(state);
|
||||
}
|
||||
|
||||
if (redraw) {
|
||||
drawHeader(state);
|
||||
plotMenuEntries(_entries, _cursorPos);
|
||||
|
@ -534,6 +538,10 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
void exit() {
|
||||
_focused = false;
|
||||
}
|
||||
|
||||
const char* title() {
|
||||
return _title;
|
||||
}
|
||||
|
@ -603,6 +611,17 @@ public:
|
|||
draw(state, redraw);
|
||||
}
|
||||
}
|
||||
|
||||
const char* summary(state_t& state) {
|
||||
size_t label_idx = *value(state) - _min;
|
||||
if (_labels.size() > 0 && label_idx >= 0 && label_idx < _labels.size()) {
|
||||
return _labels[label_idx];
|
||||
} else {
|
||||
snprintf(buffer, 12, "%+d", *value(state));
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
const char* title() {
|
||||
return _title;
|
||||
}
|
||||
|
@ -614,6 +633,7 @@ protected:
|
|||
const bool _wrap;
|
||||
const std::array<const char*, L> _labels;
|
||||
const char* _unit;
|
||||
char buffer[12];
|
||||
|
||||
void drawFrame(bool redraw) {
|
||||
if (!redraw) {
|
||||
|
@ -633,7 +653,6 @@ protected:
|
|||
display.setTextColor(WHITE, BLACK);
|
||||
drawFrame(redraw);
|
||||
|
||||
char buffer[12];
|
||||
snprintf(buffer, 12, "%+d", *value(state));
|
||||
size_t label_idx = *value(state) - _min;
|
||||
if (_labels.size() > 0 && label_idx >= 0 && label_idx < _labels.size()) {
|
||||
|
@ -747,6 +766,15 @@ public:
|
|||
draw(state, redraw, it - _choices.begin());
|
||||
}
|
||||
}
|
||||
const char* summary(state_t& state) {
|
||||
int label_idx = (state.currentPreset)->*_value;
|
||||
if (_labels.size() > 0 && label_idx >= 0 && label_idx <= _labels.size()) {
|
||||
return _labels[label_idx];
|
||||
} else {
|
||||
snprintf(buffer, 12, "%+d", state.currentPreset->*_value);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
const char* title() {
|
||||
return _title;
|
||||
}
|
||||
|
@ -755,6 +783,7 @@ private:
|
|||
T preset_t::*const _value;
|
||||
const std::array<T, N> _choices;
|
||||
const std::array<const char*, N> _labels;
|
||||
char buffer[12];
|
||||
|
||||
void draw(state_t& state, bool redraw, size_t label_idx) {
|
||||
if (redraw) {
|
||||
|
@ -769,7 +798,6 @@ private:
|
|||
display.fillRect(64, 33, 62, 29, BLACK);
|
||||
}
|
||||
|
||||
char buffer[12];
|
||||
snprintf(buffer, 12, "%+d", state.currentPreset->*_value);
|
||||
if (_labels.size() > 0 && label_idx >= 0 && label_idx <= _labels.size()) {
|
||||
plotSubOption(_labels[label_idx]);
|
||||
|
@ -779,20 +807,6 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class StatusMenu : public MenuScreen {
|
||||
public:
|
||||
StatusMenu(MenuScreen& mainMenu) : _mainMenu(mainMenu) { }
|
||||
void update(state_t& state, InputState& input, bool redraw) {
|
||||
InputState nullinput;
|
||||
if (input.changed && input.btnMenu) {
|
||||
currentMenu = &_mainMenu;
|
||||
currentMenu->update(state, nullinput, true);
|
||||
}
|
||||
};
|
||||
private:
|
||||
MenuScreen& _mainMenu;
|
||||
};
|
||||
|
||||
class ExitMenu : public MenuScreen {
|
||||
public:
|
||||
ExitMenu() {}
|
||||
|
@ -940,17 +954,17 @@ private:
|
|||
|
||||
|
||||
std::array<AdjustValue, 10> adjustValues = { {
|
||||
{"BREATH", &instrument_state_t::breathSignal, &calibration_t::breathThrValOffset, &calibration_t::breathMaxValOffset,
|
||||
{"BRTH", &instrument_state_t::breathSignal, &calibration_t::breathThrValOffset, &calibration_t::breathMaxValOffset,
|
||||
BREATH_LO_LIMIT, BREATH_HI_LIMIT, &instrument_state_t::breathZero},
|
||||
{"BITE",&instrument_state_t::biteSignal, &calibration_t::biteThrVal, &calibration_t::biteMaxVal, BITE_LO_LIMIT, BITE_HI_LIMIT, NULL},
|
||||
{"PB",&instrument_state_t::pbSignal, &calibration_t::pbMinVal, &calibration_t::pbMaxVal, PITCHB_LO_LIMIT, PITCHB_HI_LIMIT, NULL},
|
||||
{"PB Z/DZ",&instrument_state_t::pbSignal, &calibration_t::pbCenterVal, &calibration_t::pbDeadzone, PITCHB_LO_LIMIT, PITCHB_HI_LIMIT, NULL},
|
||||
{"PBDZ",&instrument_state_t::pbSignal, &calibration_t::pbCenterVal, &calibration_t::pbDeadzone, PITCHB_LO_LIMIT, PITCHB_HI_LIMIT, NULL},
|
||||
{"PB Y",&instrument_state_t::pbYSignal, &calibration_t::pbYMinVal, &calibration_t::pbYMaxVal, PITCHB_LO_LIMIT, PITCHB_HI_LIMIT, NULL},
|
||||
{"EXTRA", &instrument_state_t::extraSignal, &calibration_t::extraMinVal, &calibration_t::extraMaxVal, EXTRA_LO_LIMIT, EXTRA_HI_LIMIT, NULL},
|
||||
{"LEVER", &instrument_state_t::leverSignal, &calibration_t::leverMinVal, &calibration_t::leverMaxVal, LEVER_LO_LIMIT, LEVER_HI_LIMIT, NULL},
|
||||
{"STICK X", &instrument_state_t::stickXSignal, &calibration_t::stickXMinVal, &calibration_t::stickXMaxVal, LEVER_LO_LIMIT, LEVER_HI_LIMIT, NULL},
|
||||
{"STICK Y", &instrument_state_t::stickYSignal, &calibration_t::stickYMinVal, &calibration_t::stickYMaxVal, LEVER_LO_LIMIT, LEVER_HI_LIMIT, NULL},
|
||||
{"TOUCH", &instrument_state_t::avgCTouchSignal, &calibration_t::ctouchThrVal, &calibration_t::ctouchThrVal, CTOUCH_LO_LIMIT, CTOUCH_HI_LIMIT, NULL},
|
||||
{"EXRA", &instrument_state_t::extraSignal, &calibration_t::extraMinVal, &calibration_t::extraMaxVal, EXTRA_LO_LIMIT, EXTRA_HI_LIMIT, NULL},
|
||||
{"LEVR", &instrument_state_t::leverSignal, &calibration_t::leverMinVal, &calibration_t::leverMaxVal, LEVER_LO_LIMIT, LEVER_HI_LIMIT, NULL},
|
||||
{"ST X", &instrument_state_t::stickXSignal, &calibration_t::stickXMinVal, &calibration_t::stickXMaxVal, LEVER_LO_LIMIT, LEVER_HI_LIMIT, NULL},
|
||||
{"ST Y", &instrument_state_t::stickYSignal, &calibration_t::stickYMinVal, &calibration_t::stickYMaxVal, LEVER_LO_LIMIT, LEVER_HI_LIMIT, NULL},
|
||||
{"TCH", &instrument_state_t::avgCTouchSignal, &calibration_t::ctouchThrVal, &calibration_t::ctouchThrVal, CTOUCH_LO_LIMIT, CTOUCH_HI_LIMIT, NULL},
|
||||
}};
|
||||
|
||||
AdjustMenuScreen<10> adjustMenu("ADJUST", adjustValues);
|
||||
|
@ -1172,6 +1186,96 @@ const std::array<MenuScreen *const, 10> mainMenuEntries = {
|
|||
&exitMenu,
|
||||
};
|
||||
MainMenu<10> mainMenu(mainMenuEntries);
|
||||
|
||||
class StatusMenu : public MenuScreen {
|
||||
public:
|
||||
StatusMenu(MenuScreen& mainMenu) : _mainMenu(mainMenu) { }
|
||||
void update(state_t& state, InputState& input, bool redraw) {
|
||||
InputState nullinput;
|
||||
if (input.changed && input.btnMenu) {
|
||||
currentMenu = &_mainMenu;
|
||||
currentMenu->update(state, nullinput, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (input.changed && input.knobPreset && !redraw) {
|
||||
state.currentPresetIdx = constrain((int)state.currentPresetIdx + input.knobPreset, 0, PRESET_COUNT - 1);
|
||||
state.currentPreset = &presets[state.currentPresetIdx];
|
||||
_showValues = false;
|
||||
}
|
||||
if (input.changed && input.knobVal2 && !redraw) {
|
||||
// adjust midi channel
|
||||
state.currentPreset->MIDIchannel = constrain(state.currentPreset->MIDIchannel + input.knobVal2, 1, 16);
|
||||
_showValues = false;
|
||||
}
|
||||
if (input.changed && input.knobVal1 && !redraw) {
|
||||
// adjust octave
|
||||
state.instrument->octave = constrain(state.instrument->octave + input.knobVal1, -3, 3);
|
||||
_showValues = false;
|
||||
}
|
||||
if (input.changed && input.knobMenu && !redraw) {
|
||||
// adjust transpose
|
||||
state.instrument->transpose = constrain(state.instrument->transpose + input.knobMenu, -12, 12);
|
||||
_showValues = false;
|
||||
}
|
||||
if (input.changed && input.btnVal1 && !redraw) {
|
||||
// Toggle display if we didn't just wake up
|
||||
_showValues = !_showValues;
|
||||
}
|
||||
|
||||
draw(state);
|
||||
};
|
||||
void exit() {
|
||||
_showValues = false;
|
||||
}
|
||||
private:
|
||||
bool _showValues = false;
|
||||
MenuScreen& _mainMenu;
|
||||
void draw(state_t& state) {
|
||||
display.clearDisplay();
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 0);
|
||||
if (!_showValues) {
|
||||
display.print(" PRESET ");
|
||||
display.println(state.currentPresetIdx + 1);
|
||||
drawMenuSummary(state, midiMenu);
|
||||
drawMenuSummary(state, octaveMenu);
|
||||
drawMenuSummary(state, transposeMenu);
|
||||
drawMenuSummary(state, breathModeMenu);
|
||||
drawMenuSummary(state, fingeringMenu);
|
||||
drawMenuSummary(state, polyMenu);
|
||||
drawMenuSummary(state, rollModeMenu);
|
||||
} else {
|
||||
drawVal("BRTH: ", state.instrument->breathCCVal);
|
||||
drawVal("BITE: ", state.instrument->biteVal);
|
||||
drawVal("PORT: ", state.instrument->portamentoVal);
|
||||
drawVal("EXRA: ", state.instrument->extraVal);
|
||||
drawVal("LEVR: ", state.instrument->leverVal);
|
||||
drawVal("PB : ", state.instrument->pbVal);
|
||||
drawVal("PB Y: ", state.instrument->pbYVal);
|
||||
display.setCursor(42, 0);
|
||||
drawVal("ST X: ", state.instrument->stickXSignal);
|
||||
drawVal("ST Y: ", state.instrument->stickYSignal);
|
||||
drawVal("K1 : ", state.instrument->knobVals[0]);
|
||||
drawVal("K2 : ", state.instrument->knobVals[1]);
|
||||
drawVal("K3 : ", state.instrument->knobVals[2]);
|
||||
drawVal("K4 : ", state.instrument->knobVals[3]);
|
||||
display.setCursor(84, 0);
|
||||
drawVal("ROLL: ", state.instrument->rollCCVal);
|
||||
drawVal("TILT: ", state.instrument->tiltCCVal);
|
||||
}
|
||||
}
|
||||
void drawVal(const char *name, int val) {
|
||||
display.print(name);
|
||||
display.println(val);
|
||||
}
|
||||
void drawMenuSummary(state_t& state, MenuScreen &menu) {
|
||||
display.printf("%12s", menu.title());
|
||||
display.print(": ");
|
||||
display.println(menu.summary(state));
|
||||
}
|
||||
};
|
||||
|
||||
StatusMenu statusMenu = StatusMenu(mainMenu);
|
||||
|
||||
//***********************************************************
|
||||
|
@ -1238,6 +1342,7 @@ void displayOff(state_t &state) {
|
|||
display.clearDisplay();
|
||||
display.display();
|
||||
display.ssd1306_command(SSD1306_DISPLAYOFF);
|
||||
currentMenu->exit();
|
||||
currentMenu = &statusMenu;
|
||||
displayOn = false;
|
||||
}
|
||||
|
@ -1278,7 +1383,7 @@ void initDisplay() {
|
|||
}
|
||||
|
||||
bool inMenu() {
|
||||
return currentMenu != &statusMenu;
|
||||
return displayOn;
|
||||
}
|
||||
|
||||
void handleMenu(state_t& state, bool draw) {
|
||||
|
|
|
@ -33,7 +33,10 @@ class MenuScreen {
|
|||
public:
|
||||
MenuScreen() {};
|
||||
virtual const char *title() { return ""; };
|
||||
virtual const char* summary(state_t& state) { return ""; };
|
||||
virtual void update(state_t &state, InputState &input, bool redraw) = 0;
|
||||
|
||||
virtual void exit() { };
|
||||
virtual ~MenuScreen() {};
|
||||
};
|
||||
|
||||
|
|
|
@ -419,68 +419,47 @@ void portamento_() {
|
|||
//***********************************************************
|
||||
|
||||
void sendCC() {
|
||||
if (ExtraControl::CC == state.currentPreset->biteControl) {
|
||||
int biteVal = mapConstrain(instrument.biteSignal, calibration.biteThrVal, calibration.biteMaxVal, 127, 0);
|
||||
|
||||
if (biteVal != instrument.biteVal) {
|
||||
midiSendControlChange(state.currentPreset->biteCC, biteVal);
|
||||
}
|
||||
instrument.biteVal = biteVal;
|
||||
int biteVal = mapConstrain(instrument.biteSignal, calibration.biteThrVal, calibration.biteMaxVal, 127, 0);
|
||||
if (ExtraControl::CC == state.currentPreset->biteControl && biteVal != instrument.biteVal) {
|
||||
midiSendControlChange(state.currentPreset->biteCC, biteVal);
|
||||
}
|
||||
instrument.biteVal = biteVal;
|
||||
|
||||
if (ExtraControl::CC == state.currentPreset->extraControl) {
|
||||
int extraVal = mapConstrain(instrument.extraSignal, calibration.extraMinVal, calibration.extraMaxVal, 0, 127);
|
||||
|
||||
if (extraVal != instrument.extraVal) {
|
||||
midiSendControlChange(state.currentPreset->extraCC, extraVal);
|
||||
}
|
||||
instrument.extraVal = extraVal;
|
||||
int extraVal = mapConstrain(instrument.extraSignal, calibration.extraMinVal, calibration.extraMaxVal, 0, 127);
|
||||
if (ExtraControl::CC == state.currentPreset->extraControl && extraVal != instrument.extraVal) {
|
||||
midiSendControlChange(state.currentPreset->extraCC, extraVal);
|
||||
}
|
||||
instrument.extraVal = extraVal;
|
||||
|
||||
int leverVal = mapConstrain(instrument.leverSignal, calibration.leverMinVal, calibration.leverMaxVal, 0, 127);
|
||||
if (ExtraControl::CC == state.currentPreset->leverControl) {
|
||||
if (leverVal != instrument.leverVal) {
|
||||
midiSendControlChange(state.currentPreset->leverCC, leverVal);
|
||||
}
|
||||
if (ExtraControl::CC == state.currentPreset->leverControl && leverVal != instrument.leverVal) {
|
||||
midiSendControlChange(state.currentPreset->leverCC, leverVal);
|
||||
}
|
||||
instrument.leverVal = leverVal;
|
||||
|
||||
if (ExtraControl::CC == state.currentPreset->pbControl) {
|
||||
int pbVal = mapConstrain(instrument.pbSignal, calibration.pbMinVal, calibration.pbMaxVal, 0, 127);
|
||||
|
||||
if (pbVal != instrument.pbVal) {
|
||||
midiSendControlChange(state.currentPreset->pbCC, pbVal);
|
||||
}
|
||||
instrument.pbVal = pbVal;
|
||||
int pbVal = mapConstrain(instrument.pbSignal, calibration.pbMinVal, calibration.pbMaxVal, 0, 127);
|
||||
if (ExtraControl::CC == state.currentPreset->pbControl && pbVal != instrument.pbVal) {
|
||||
midiSendControlChange(state.currentPreset->pbCC, pbVal);
|
||||
}
|
||||
instrument.pbVal = pbVal;
|
||||
|
||||
if (state.currentPreset->pbYCC) {
|
||||
int pbYVal = mapConstrain(instrument.pbYSignal, calibration.pbYMinVal, calibration.pbYMaxVal, 0, 127);
|
||||
|
||||
if (pbYVal != instrument.pbYVal) {
|
||||
midiSendControlChange(state.currentPreset->pbYCC, pbYVal);
|
||||
}
|
||||
instrument.pbYVal = pbYVal;
|
||||
int pbYVal = mapConstrain(instrument.pbYSignal, calibration.pbYMinVal, calibration.pbYMaxVal, 0, 127);
|
||||
if (state.currentPreset->pbYCC && pbYVal != instrument.pbYVal) {
|
||||
midiSendControlChange(state.currentPreset->pbYCC, pbYVal);
|
||||
}
|
||||
instrument.pbYVal = pbYVal;
|
||||
|
||||
if (state.currentPreset->stickXCC) {
|
||||
int stickXVal = mapConstrain(instrument.stickXSignal, calibration.stickXMinVal, calibration.stickXMaxVal, 0, 127);
|
||||
|
||||
if (stickXVal != instrument.stickXVal) {
|
||||
midiSendControlChange(state.currentPreset->stickXCC, stickXVal);
|
||||
}
|
||||
instrument.stickXVal = stickXVal;
|
||||
int stickXVal = mapConstrain(instrument.stickXSignal, calibration.stickXMinVal, calibration.stickXMaxVal, 0, 127);
|
||||
if (state.currentPreset->stickXCC && stickXVal != instrument.stickXVal) {
|
||||
midiSendControlChange(state.currentPreset->stickXCC, stickXVal);
|
||||
}
|
||||
instrument.stickXVal = stickXVal;
|
||||
|
||||
if (state.currentPreset->stickYCC) {
|
||||
int stickYVal = mapConstrain(instrument.stickYSignal, calibration.stickYMinVal, calibration.stickYMaxVal, 0, 127);
|
||||
|
||||
if (stickYVal != instrument.stickYVal) {
|
||||
midiSendControlChange(state.currentPreset->stickYCC, stickYVal);
|
||||
}
|
||||
instrument.stickYVal = stickYVal;
|
||||
int stickYVal = mapConstrain(instrument.stickYSignal, calibration.stickYMinVal, calibration.stickYMaxVal, 0, 127);
|
||||
if (state.currentPreset->stickYCC && stickYVal != instrument.stickYVal) {
|
||||
midiSendControlChange(state.currentPreset->stickYCC, stickYVal);
|
||||
}
|
||||
|
||||
instrument.stickYVal = stickYVal;
|
||||
|
||||
if (!inMenu()) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue