refactor cv mod to allow both cv mods configurable per channel. Fix euclidean sum mod. update large font.
This commit is contained in:
@ -66,15 +66,6 @@ void loop() {
|
||||
// Only apply CV to the channel when the current channel has cv
|
||||
// mod configured.
|
||||
if (ch.isCvModActive()) {
|
||||
// hack -- do not apply mod to euclidean rhythm when editing.
|
||||
bool editing_euc;
|
||||
editing_euc |= ch.getCvDestination() == CV_DEST_EUC_STEPS;
|
||||
editing_euc |= ch.getCvDestination() == CV_DEST_EUC_HITS;
|
||||
editing_euc &= (app.selected_channel - 1) == i;
|
||||
editing_euc &= app.editing_param;
|
||||
if (editing_euc) {
|
||||
continue;
|
||||
}
|
||||
ch.applyCvMod(cv1, cv2);
|
||||
}
|
||||
}
|
||||
@ -263,16 +254,16 @@ void editChannelParameter(int val) {
|
||||
case PARAM_CH_EUC_HITS:
|
||||
ch.setHits(ch.getHits() + val);
|
||||
break;
|
||||
case PARAM_CH_CV_SRC: {
|
||||
byte source = static_cast<int>(ch.getCvSource());
|
||||
updateSelection(source, val, CV_LAST);
|
||||
ch.setCvSource(static_cast<CvSource>(source));
|
||||
case PARAM_CH_CV1_DEST: {
|
||||
byte dest = static_cast<int>(ch.getCv1Dest());
|
||||
updateSelection(dest, val, CV_DEST_LAST);
|
||||
ch.setCv1Dest(static_cast<CvDestination>(dest));
|
||||
break;
|
||||
}
|
||||
case PARAM_CH_CV_DEST: {
|
||||
byte dest = static_cast<int>(ch.getCvDestination());
|
||||
case PARAM_CH_CV2_DEST: {
|
||||
byte dest = static_cast<int>(ch.getCv2Dest());
|
||||
updateSelection(dest, val, CV_DEST_LAST);
|
||||
ch.setCvDestination(static_cast<CvDestination>(dest));
|
||||
ch.setCv2Dest(static_cast<CvDestination>(dest));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,8 +43,8 @@ enum ParamsChannelPage : uint8_t {
|
||||
PARAM_CH_SWING,
|
||||
PARAM_CH_EUC_STEPS,
|
||||
PARAM_CH_EUC_HITS,
|
||||
PARAM_CH_CV_SRC,
|
||||
PARAM_CH_CV_DEST,
|
||||
PARAM_CH_CV1_DEST,
|
||||
PARAM_CH_CV2_DEST,
|
||||
PARAM_CH_LAST,
|
||||
};
|
||||
|
||||
|
||||
@ -6,14 +6,7 @@
|
||||
|
||||
#include "euclidean.h"
|
||||
|
||||
// Enums for CV configuration
|
||||
enum CvSource : uint8_t {
|
||||
CV_NONE,
|
||||
CV_1,
|
||||
CV_2,
|
||||
CV_LAST,
|
||||
};
|
||||
|
||||
// Enums for CV Mod destination
|
||||
enum CvDestination : uint8_t {
|
||||
CV_DEST_NONE,
|
||||
CV_DEST_MOD,
|
||||
@ -45,9 +38,8 @@ class Channel {
|
||||
base_duty_cycle = 50;
|
||||
base_offset = 0;
|
||||
base_swing = 50;
|
||||
|
||||
cv_source = CV_NONE;
|
||||
cv_destination = CV_DEST_NONE;
|
||||
base_euc_steps = 1;
|
||||
base_euc_hits = 1;
|
||||
|
||||
cvmod_clock_mod_index = base_clock_mod_index;
|
||||
cvmod_probability = base_probability;
|
||||
@ -62,40 +54,56 @@ class Channel {
|
||||
|
||||
void setClockMod(int index) {
|
||||
base_clock_mod_index = constrain(index, 0, MOD_CHOICE_SIZE - 1);
|
||||
if (!isCvModActive()) {
|
||||
if (cv1_dest != CV_DEST_MOD && cv2_dest != CV_DEST_MOD) {
|
||||
cvmod_clock_mod_index = base_clock_mod_index;
|
||||
}
|
||||
}
|
||||
|
||||
void setProbability(int prob) {
|
||||
base_probability = constrain(prob, 0, 100);
|
||||
if (!isCvModActive()) {
|
||||
if (cv1_dest != CV_DEST_PROB && cv2_dest != CV_DEST_PROB) {
|
||||
cvmod_probability = base_probability;
|
||||
}
|
||||
}
|
||||
|
||||
void setDutyCycle(int duty) {
|
||||
base_duty_cycle = constrain(duty, 1, 99);
|
||||
if (!isCvModActive()) {
|
||||
if (cv1_dest != CV_DEST_DUTY && cv2_dest != CV_DEST_DUTY) {
|
||||
cvmod_duty_cycle = base_duty_cycle;
|
||||
}
|
||||
}
|
||||
|
||||
void setOffset(int off) {
|
||||
base_offset = constrain(off, 0, 99);
|
||||
if (!isCvModActive()) {
|
||||
if (cv1_dest != CV_DEST_OFFSET && cv2_dest != CV_DEST_OFFSET) {
|
||||
cvmod_offset = base_offset;
|
||||
}
|
||||
}
|
||||
void setSwing(int val) {
|
||||
base_swing = constrain(val, 50, 95);
|
||||
if (!isCvModActive()) {
|
||||
if (cv1_dest != CV_DEST_SWING && cv2_dest != CV_DEST_SWING) {
|
||||
cvmod_swing = base_swing;
|
||||
}
|
||||
}
|
||||
|
||||
void setCvSource(CvSource source) { cv_source = source; }
|
||||
void setCvDestination(CvDestination dest) { cv_destination = dest; }
|
||||
// Euclidean
|
||||
void setSteps(int val) {
|
||||
base_euc_steps = constrain(val, 1, MAX_PATTERN_LEN);
|
||||
if (cv1_dest != CV_DEST_EUC_STEPS && cv2_dest != CV_DEST_EUC_STEPS) {
|
||||
pattern.SetSteps(val);
|
||||
}
|
||||
}
|
||||
void setHits(int val) {
|
||||
base_euc_hits = constrain(val, 1, base_euc_steps);
|
||||
if (cv1_dest != CV_DEST_EUC_HITS && cv2_dest != CV_DEST_EUC_HITS) {
|
||||
pattern.SetHits(val);
|
||||
}
|
||||
}
|
||||
|
||||
void setCv1Dest(CvDestination dest) { cv1_dest = dest; }
|
||||
void setCv2Dest(CvDestination dest) { cv2_dest = dest; }
|
||||
CvDestination getCv1Dest() const { return cv1_dest; }
|
||||
CvDestination getCv2Dest() const { return cv2_dest; }
|
||||
|
||||
// Getters (Get the BASE value for editing or cv modded value for display)
|
||||
|
||||
@ -105,15 +113,10 @@ class Channel {
|
||||
int getSwing(bool withCvMod = false) const { return withCvMod ? cvmod_swing : base_swing; }
|
||||
int getClockMod(bool withCvMod = false) const { return pgm_read_word_near(&clock_mod[getClockModIndex(withCvMod)]); }
|
||||
int getClockModIndex(bool withCvMod = false) const { return withCvMod ? cvmod_clock_mod_index : base_clock_mod_index; }
|
||||
CvSource getCvSource() { return cv_source; }
|
||||
CvDestination getCvDestination() { return cv_destination; }
|
||||
bool isCvModActive() const { return cv_source != CV_NONE && cv_destination != CV_DEST_NONE; }
|
||||
bool isCvModActive() const { return cv1_dest != CV_DEST_NONE || cv2_dest != CV_DEST_NONE; }
|
||||
|
||||
// Euclidean
|
||||
void setSteps(int val) { pattern.SetSteps(val); }
|
||||
void setHits(int val) { pattern.SetHits(val); }
|
||||
byte getSteps() { return pattern.GetSteps(); }
|
||||
byte getHits() { return pattern.GetHits(); }
|
||||
byte getSteps(bool withCvMod = false) const { return withCvMod ? pattern.GetSteps() : base_euc_steps; }
|
||||
byte getHits(bool withCvMod = false) const { return withCvMod ? pattern.GetHits() : base_euc_hits; }
|
||||
|
||||
/**
|
||||
* @brief Processes a clock tick and determines if the output should be high or low.
|
||||
@ -163,54 +166,55 @@ class Channel {
|
||||
}
|
||||
}
|
||||
|
||||
void applyCvMod(int cv1_value, int cv2_value) {
|
||||
// Use the CV value for current selected cv source.
|
||||
int value = (cv_source == CV_1) ? cv1_value : cv2_value;
|
||||
|
||||
void applyCvMod(int cv1_val, int cv2_val) {
|
||||
// Calculate and store cv modded values using bipolar mapping.
|
||||
// Default to base value if not the current CV destination.
|
||||
|
||||
cvmod_clock_mod_index =
|
||||
(cv_destination == CV_DEST_MOD)
|
||||
? constrain(base_clock_mod_index + map(value, -512, 512, -10, 10), 0, MOD_CHOICE_SIZE - 1)
|
||||
: base_clock_mod_index;
|
||||
// Note: This is optimized for cpu performance. This method is called
|
||||
// from the main loop and stores the cv mod values. This reduces CPU
|
||||
// cycles inside the internal clock interrupt, which is preferrable.
|
||||
// However, if RAM usage grows too much, we have an opportunity to
|
||||
// refactor this to store just the CV read values, and calculate the
|
||||
// cv mod value per channel inside the getter methods by passing cv
|
||||
// values. This would reduce RAM usage, but would introduce a
|
||||
// significant CPU cost, which may have undesirable performance issues.
|
||||
|
||||
cvmod_probability =
|
||||
(cv_destination == CV_DEST_PROB)
|
||||
? constrain(base_probability + map(value, -512, 512, -50, 50), 0, 100)
|
||||
: base_probability;
|
||||
int dest_mod = calculateMod(CV_DEST_MOD, cv1_val, cv2_val, -10, 10);
|
||||
cvmod_clock_mod_index = constrain(base_clock_mod_index + dest_mod, 0, 100);
|
||||
|
||||
cvmod_duty_cycle =
|
||||
(cv_destination == CV_DEST_DUTY)
|
||||
? constrain(base_duty_cycle + map(value, -512, 512, -50, 50), 1, 99)
|
||||
: base_duty_cycle;
|
||||
int prob_mod = calculateMod(CV_DEST_PROB, cv1_val, cv2_val, -50, 50);
|
||||
cvmod_probability = constrain(base_probability + prob_mod, 0, 100);
|
||||
|
||||
cvmod_offset =
|
||||
(cv_destination == CV_DEST_OFFSET)
|
||||
? constrain(base_offset + map(value, -512, 512, -50, 50), 0, 99)
|
||||
: base_offset;
|
||||
int duty_mod = calculateMod(CV_DEST_DUTY, cv1_val, cv2_val, -50, 50);
|
||||
cvmod_duty_cycle = constrain(base_duty_cycle + duty_mod, 1, 99);
|
||||
|
||||
cvmod_swing =
|
||||
(cv_destination == CV_DEST_SWING)
|
||||
? constrain(base_swing + map(value, -512, 512, -25, 25), 50, 95)
|
||||
: base_swing;
|
||||
int offset_mod = calculateMod(CV_DEST_OFFSET, cv1_val, cv2_val, -50, 50);
|
||||
cvmod_offset = constrain(base_offset + offset_mod, 0, 99);
|
||||
|
||||
if (cv_destination == CV_DEST_EUC_STEPS) {
|
||||
pattern.SetSteps(map(value, -512, 512, 0, MAX_PATTERN_LEN));
|
||||
}
|
||||
int swing_mod = calculateMod(CV_DEST_SWING, cv1_val, cv2_val, -25, 25);
|
||||
cvmod_swing = constrain(base_swing + swing_mod, 50, 95);
|
||||
|
||||
if (cv_destination == CV_DEST_EUC_HITS) {
|
||||
pattern.SetHits(map(value, -512, 512, 0, pattern.GetSteps()));
|
||||
}
|
||||
int step_mod = calculateMod(CV_DEST_EUC_STEPS, cv1_val, cv2_val, 0, MAX_PATTERN_LEN);
|
||||
pattern.SetSteps(base_euc_steps + step_mod);
|
||||
|
||||
int hit_mod = calculateMod(CV_DEST_EUC_HITS, cv1_val, cv2_val, 0, MAX_PATTERN_LEN);
|
||||
pattern.SetHits(base_euc_hits + hit_mod);
|
||||
}
|
||||
|
||||
private:
|
||||
int calculateMod(CvDestination dest, int cv1_val, int cv2_val, int min_range, int max_range) {
|
||||
int mod1 = (cv1_dest == dest) ? map(cv1_val, -512, 512, min_range, max_range) : 0;
|
||||
int mod2 = (cv2_dest == dest) ? map(cv2_val, -512, 512, min_range, max_range) : 0;
|
||||
return mod1 + mod2;
|
||||
}
|
||||
// User-settable base values.
|
||||
byte base_clock_mod_index;
|
||||
byte base_probability;
|
||||
byte base_duty_cycle;
|
||||
byte base_offset;
|
||||
byte base_swing;
|
||||
byte base_euc_steps;
|
||||
byte base_euc_hits;
|
||||
|
||||
// Base value with cv mod applied.
|
||||
byte cvmod_clock_mod_index;
|
||||
@ -219,9 +223,9 @@ class Channel {
|
||||
byte cvmod_offset;
|
||||
byte cvmod_swing;
|
||||
|
||||
// CV configuration
|
||||
CvSource cv_source = CV_NONE;
|
||||
CvDestination cv_destination = CV_DEST_NONE;
|
||||
// CV mod configuration
|
||||
CvDestination cv1_dest;
|
||||
CvDestination cv2_dest;
|
||||
|
||||
// Euclidean pattern
|
||||
Pattern pattern;
|
||||
|
||||
@ -9,6 +9,11 @@
|
||||
// UI Display functions for drawing the UI to the OLED display.
|
||||
//
|
||||
|
||||
/*
|
||||
* Font: velvetscreen.bdf 9pt
|
||||
* https://stncrn.github.io/u8g2-unifont-helper/
|
||||
* "%/0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
*/
|
||||
const uint8_t TEXT_FONT[437] U8G2_FONT_SECTION("velvetscreen") PROGMEM =
|
||||
"\64\0\2\2\3\3\2\3\4\5\5\0\0\5\0\5\0\0\221\0\0\1\230 \4\200\134%\11\255tT"
|
||||
"R\271RI(\6\252\334T\31)\7\252\134bJ\12+\7\233\345\322J\0,\5\221T\4-\5\213"
|
||||
@ -25,8 +30,13 @@ const uint8_t TEXT_FONT[437] U8G2_FONT_SECTION("velvetscreen") PROGMEM =
|
||||
"\7p\10\255\364V\266\323\2q\7\255\364\216\257\5r\10\253d\242\32*\2t\6\255t\376#w\11"
|
||||
"\255\364V\245FN\13x\6\233dR\7\0\0\0\4\377\377\0";
|
||||
|
||||
const uint8_t LARGE_FONT[916] U8G2_FONT_SECTION("stk-l") PROGMEM =
|
||||
"#\0\4\4\4\5\2\1\6\17\30\1\0\27\0\0\0\1\77\0\0\3w%'\17\37\313\330R#&"
|
||||
/*
|
||||
* Font: STK-L.bdf 36pt
|
||||
* https://stncrn.github.io/u8g2-unifont-helper/
|
||||
* "%/0123456789ACDEFINORSTUVXx"
|
||||
*/
|
||||
const uint8_t LARGE_FONT[715] U8G2_FONT_SECTION("stk-l") =
|
||||
"\33\0\4\4\4\5\2\1\6\20\30\0\0\27\0\0\0\1\77\0\0\2\256%'\17\37\313\330R#&"
|
||||
"\32!F\14\211I\310\24!\65\204(MF\21)Cd\304\10\62b\14\215\60Vb\334\20\0/\14"
|
||||
"\272\336\336d\244\350\263q\343\0\60\37|\377\216!%*\10\35\263\253ChD\30\21bB\14\242S"
|
||||
"\306lv\210\204\22Ef\0\61\24z\337\322\60R\205\314\234\31\61F\310\270\371\177\224\42\3\62\33|"
|
||||
@ -37,24 +47,18 @@ const uint8_t LARGE_FONT[916] U8G2_FONT_SECTION("stk-l") PROGMEM =
|
||||
"\234\335\235\42\261&\325\31\0\67\23|\377\302\212\7)\347Crt\70\345\300\221\363\16\0\70 |\377"
|
||||
"\216)\64*\10\35\263\354\20\11\42d\20\235BC\204\4\241cvv\210\204\32Tf\0\71\32|\377"
|
||||
"\216)\64*\10\35\263\263C$\226\250I\71_\14\42\241\6\225\31\0A\26}\17S\271Si(\31"
|
||||
"\65d\324\210q\366\356\301w\366\273\1B$}\17C\42\65KF\221\30\66b\330\210a#\206\215\30"
|
||||
"Eb\311&\243H\14;g\317\36\204`\261\4\0C\27}\17\317\251\64K\10!\63:\377\247\304F"
|
||||
"\20\42\261F\21\22\0D\33}\17C\42\65KF\15\31\66b\330\210q\366\77;\66b\24\211%j"
|
||||
"\22\1E\21|\377\302\7)\347%\42\214F\316/\37<\60F\20|\377\302\7)\347\313\64\331\214\234"
|
||||
"\177\11\0G\31\216\37\17*\65L\206\35\264v>\322\241\15\217\221 \65\204\215\262\63\0H\17|\377"
|
||||
"\302\60\373g\17\36\60\263\177\66\0I\7so\302\37$J\22|\377\346\374\377\322\230\261C\210H\250"
|
||||
"Ae\6\0K\42|\377\302\60S\247F\14\42\61h\310\30\42c&!\63\202\320\251\64JV\14\42"
|
||||
"\61\352\230\375l\0L\15{\357\302\300\371\377\37>x\60\0M$}\17\203\310r\346N\245Q\263\202"
|
||||
"E\12)L\224\60Q\302\310\20#C\214\14\61\23\306L\30s\366\335\0N#}\17\203@s\346\216"
|
||||
"\35C\205*Q\42\23cL\214\61\62\304\310\20\63#\314\214\60\224\25f\327\231\33O\26}\17\317\251"
|
||||
"\64KF\215\30g\377\337\215\30\65dM\252\63\0P\26|\377B\32%+F\35\263W\207H\254H"
|
||||
"\203h\344\374%\0Q\31}\17S\261\64KF\215\30g\377oF\230\31q\246\210\42E%F\0R"
|
||||
"\65d\324\210q\366\356\301w\366\273\1C\27}\17\317\251\64K\10!\63:\377\247\304F\20\42\261F"
|
||||
"\21\22\0D\33}\17C\42\65KF\15\31\66b\330\210q\366\77;\66b\24\211%j\22\1E\21"
|
||||
"|\377\302\7)\347%\42\214F\316/\37<\60F\20|\377\302\7)\347\313\64\331\214\234\177\11\0I"
|
||||
"\7so\302\37$N#}\17\203@s\346\216\35C\205*Q\42\23cL\214\61\62\304\310\20\63#"
|
||||
"\314\214\60\224\25f\327\231\33O\26}\17\317\251\64KF\215\30g\377\337\215\30\65dM\252\63\0R"
|
||||
"\61\216\37\203\242\65L\206\221\30\67b\334\210q#\306\215\30\67b\30\211QD\230(J\65d\330\230"
|
||||
"Qc\10\315j\314(\42\303H\214\33\61\356\340\0S!\216\37\317\261DKH\221\30\67b\334\210\261"
|
||||
"c)M\246Ji\331\331\32\64\207\212D\223Uh\0T\15}\17\303\7\251\206\316\377\377\12\0U\21"
|
||||
"|\377\302\60\373\377\317F\14\32\242\6\225\31\0X)~\37\303@\203\307H\14\33B\210\14\21RC"
|
||||
"\206\241\63h\222(I\203\346\220\15\31E\204\14!\42\303F\20;h\341\0x\24\312\336\302 CG"
|
||||
"H\240\61E\312\14\222)\6Y\64\0\0\0\0\4\377\377\0";
|
||||
"Qc\10\315j\314(\42\303H\214\33\61\356\340\0S\42\216\37\317\261DKH\221\30\67b\334\210\261"
|
||||
"c)M\226-\331\301c\307\32\64\207\212D\223Uh\0T\15}\17\303\7\251\206\316\377\377\12\0U"
|
||||
"\21|\377\302\60\373\377\317F\14\32\242\6\225\31\0V\26\177\375\302H\373\377\345\210qCH\221\241\212"
|
||||
"\4\271\223e\207\1X)~\37\303@\203\307H\14\33B\210\14\21RC\206\241\63h\222(I\203\346"
|
||||
"\220\15\31E\204\14!\42\303F\20;h\341\0x\24\312\336\302 CGH\240\61E\312\14\222)\6"
|
||||
"Y\64\0\0\0\0\4\377\377\0";
|
||||
|
||||
#define play_icon_width 14
|
||||
#define play_icon_height 14
|
||||
@ -287,31 +291,17 @@ void DisplayChannelPage() {
|
||||
swingDivisionMark();
|
||||
break;
|
||||
case PARAM_CH_EUC_STEPS:
|
||||
mainText = String(ch.getSteps());
|
||||
mainText = String(ch.getSteps(withCvMod));
|
||||
subText = "EUCLID STEPS";
|
||||
break;
|
||||
case PARAM_CH_EUC_HITS:
|
||||
mainText = String(ch.getHits());
|
||||
mainText = String(ch.getHits(withCvMod));
|
||||
subText = "EUCLID HITS";
|
||||
break;
|
||||
case PARAM_CH_CV_SRC: {
|
||||
mainText = F("SRC");
|
||||
switch (ch.getCvSource()) {
|
||||
case CV_NONE:
|
||||
subText = F("NONE");
|
||||
break;
|
||||
case CV_1:
|
||||
subText = F("CV 1");
|
||||
break;
|
||||
case CV_2:
|
||||
subText = F("CV 2");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PARAM_CH_CV_DEST: {
|
||||
mainText = F("DEST");
|
||||
switch (ch.getCvDestination()) {
|
||||
case PARAM_CH_CV1_DEST:
|
||||
case PARAM_CH_CV2_DEST: {
|
||||
mainText = (app.selected_param == PARAM_CH_CV1_DEST) ? F("CV1") : F("CV2");
|
||||
switch ((app.selected_param == PARAM_CH_CV1_DEST) ? ch.getCv1Dest() : ch.getCv2Dest()) {
|
||||
case CV_DEST_NONE:
|
||||
subText = F("NONE");
|
||||
break;
|
||||
@ -347,7 +337,7 @@ void DisplayChannelPage() {
|
||||
// Draw Channel Page menu items
|
||||
String menu_items[PARAM_CH_LAST] = {
|
||||
F("MOD"), F("PROBABILITY"), F("DUTY"), F("OFFSET"), F("SWING"), F("EUCLID STEPS"),
|
||||
F("EUCLID HITS"), F("CV SOURCE"), F("CV DEST")};
|
||||
F("EUCLID HITS"), F("CV1 MOD"), F("CV2 MOD")};
|
||||
drawMenuItems(menu_items, PARAM_CH_LAST);
|
||||
}
|
||||
|
||||
|
||||
@ -46,9 +46,9 @@ class Pattern {
|
||||
|
||||
void Reset() { step_index_ = 0; }
|
||||
|
||||
uint8_t GetSteps() { return steps_; }
|
||||
uint8_t GetHits() { return hits_; }
|
||||
uint8_t GetStepIndex() { return step_index_; }
|
||||
uint8_t GetSteps() const { return steps_; }
|
||||
uint8_t GetHits() const { return hits_; }
|
||||
uint8_t GetStepIndex() const { return step_index_; }
|
||||
|
||||
Step NextStep() {
|
||||
if (steps_ == 0) return REST;
|
||||
|
||||
@ -29,10 +29,10 @@ bool StateManager::initialize(AppState& app) {
|
||||
ch.setDutyCycle(saved_ch_state.base_duty_cycle);
|
||||
ch.setOffset(saved_ch_state.base_offset);
|
||||
ch.setSwing(saved_ch_state.base_shuffle);
|
||||
ch.setCvSource(static_cast<CvSource>(saved_ch_state.cv_source));
|
||||
ch.setCvDestination(static_cast<CvDestination>(saved_ch_state.cv_destination));
|
||||
ch.setSteps(saved_ch_state.euc_steps);
|
||||
ch.setHits(saved_ch_state.euc_hits);
|
||||
ch.setSteps(saved_ch_state.base_euc_steps);
|
||||
ch.setHits(saved_ch_state.base_euc_hits);
|
||||
ch.setCv1Dest(static_cast<CvDestination>(saved_ch_state.cv1_dest));
|
||||
ch.setCv1Dest(static_cast<CvDestination>(saved_ch_state.cv2_dest));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -112,10 +112,10 @@ void StateManager::_saveState(const AppState& app) {
|
||||
save_ch.base_duty_cycle = ch.getDutyCycle(false);
|
||||
save_ch.base_offset = ch.getOffset(false);
|
||||
save_ch.base_shuffle = ch.getSwing();
|
||||
save_ch.cv_source = static_cast<byte>(ch.getCvSource());
|
||||
save_ch.cv_destination = static_cast<byte>(ch.getCvDestination());
|
||||
save_ch.euc_steps = ch.getSteps();
|
||||
save_ch.euc_hits = ch.getHits();
|
||||
save_ch.base_euc_steps = ch.getSteps();
|
||||
save_ch.base_euc_hits = ch.getHits();
|
||||
save_ch.cv1_dest = static_cast<byte>(ch.getCv1Dest());
|
||||
save_ch.cv2_dest = static_cast<byte>(ch.getCv2Dest());
|
||||
}
|
||||
EEPROM.put(sizeof(Metadata), save_data);
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ struct AppState;
|
||||
|
||||
// Define the constants for the current firmware.
|
||||
const char SKETCH_NAME[] = "Gravity";
|
||||
const byte SKETCH_VERSION = 5;
|
||||
const byte SKETCH_VERSION = 6;
|
||||
|
||||
// Define the minimum amount of time between EEPROM writes.
|
||||
static const unsigned long SAVE_DELAY_MS = 2000;
|
||||
@ -42,10 +42,10 @@ class StateManager {
|
||||
byte base_duty_cycle;
|
||||
byte base_offset;
|
||||
byte base_shuffle;
|
||||
byte cv_source; // Cast the CvSource enum to a byte for storage
|
||||
byte cv_destination; // Cast the CvDestination enum as a byte for storage
|
||||
byte euc_steps;
|
||||
byte euc_hits;
|
||||
byte base_euc_steps;
|
||||
byte base_euc_hits;
|
||||
byte cv1_dest; // Cast the CvDestination enum as a byte for storage
|
||||
byte cv2_dest; // Cast the CvDestination enum as a byte for storage
|
||||
};
|
||||
// This struct holds all the parameters we want to save.
|
||||
struct EepromData {
|
||||
|
||||
Reference in New Issue
Block a user