Improved menu status display

Added ability to adjust key params from status and load preset
This commit is contained in:
Brian Hrebec 2024-11-09 11:39:35 -06:00
parent 7219872a14
commit a2f2fb260d
5 changed files with 165 additions and 84 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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) {

View file

@ -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() {};
};

View file

@ -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++) {