about summary refs log tree commit diff
path: root/Classes.h
diff options
context:
space:
mode:
authorNicholas Fox <nicholas.k.fox@gmail.com>2024-04-23 22:00:00 -0400
committerZach DeCook <zachdecook@librem.one>2024-04-26 12:58:26 -0400
commitdc5a26d411bc90b35ad8fea64fecae120e93cf7e (patch)
tree038fe00d54f1fbd14a807eafe6dca87563f6bfbf /Classes.h
parent79201aa4ff8e9d0ffbcfcb0ad4bd511b1f4bacd1 (diff)
downloadHexBoard-dc5a26d411bc90b35ad8fea64fecae120e93cf7e.tar.gz
Updates:
MENU
1) even more preset scales in the non-12 tunings -- some are super funky!
2) transpose should be working again
3) moved key signature change into the Scales page
4) wheel speed options are restored

FEATURES
1) POLYPHONIC BUZZER
2) wheel function back to "regular"
3) color palette improvements

STILL NOT QUITE WORKING
1) buzzer only works in polyphony mode for now -- haven't gotten mono
or arpeggio working right yet

I moved some stuff into .h headers, but no changes to the patches you
need for rotary / g8u2.
Diffstat (limited to 'Classes.h')
-rw-r--r--Classes.h158
1 files changed, 158 insertions, 0 deletions
diff --git a/Classes.h b/Classes.h
new file mode 100644
index 0000000..133d3a5
--- /dev/null
+++ b/Classes.h
@@ -0,0 +1,158 @@
+// class definitions are in a header so that

+// they get read before compiling the main program.

+

+class tuningDef {

+public:

+  std::string name; // limit is 17 characters for GEM menu

+  byte cycleLength; // steps before period/cycle/octave repeats

+  float stepSize;   // in cents, 100 = "normal" semitone.

+  SelectOptionInt keyChoices[MAX_SCALE_DIVISIONS];

+  int spanCtoA() {

+    return (- keyChoices[0].val_int);

+  };

+};

+

+class layoutDef {

+public:

+  std::string name;    // limit is 17 characters for GEM menu

+  bool isPortrait;     // affects orientation of the GEM menu only.

+  byte hexMiddleC;     // instead of "what note is button 1", "what button is the middle"

+  int8_t acrossSteps;  // defined this way to be compatible with original v1.1 firmare

+  int8_t dnLeftSteps;  // defined this way to be compatible with original v1.1 firmare

+  byte tuning;         // index of the tuning that this layout is designed for

+};

+

+class colorDef {

+public:

+  float hue;

+  byte sat;

+  byte val;

+  colorDef mixWithWhite() {

+    colorDef temp;

+    temp.hue = this->hue;

+    temp.sat = ((this->sat > SAT_TINT) ? SAT_TINT : this->sat);

+    temp.val = VALUE_FULL;

+    return temp;

+  };

+};

+

+class paletteDef {

+public:

+  colorDef swatch[MAX_SCALE_DIVISIONS]; // the different colors used in this palette

+  byte colorNum[MAX_SCALE_DIVISIONS];   // map key (c,d...) to swatches

+  colorDef getColor(byte givenStepFromC) {

+    return swatch[colorNum[givenStepFromC] - 1];

+  };

+  float getHue(byte givenStepFromC) {

+    return getColor(givenStepFromC).hue;

+  };

+  byte getSat(byte givenStepFromC) {

+    return getColor(givenStepFromC).sat;

+  };

+  byte getVal(byte givenStepFromC) {

+    return getColor(givenStepFromC).val;

+  };

+};

+

+class buttonDef {

+public:

+  byte     btnState = 0;        // binary 00 = off, 01 = just pressed, 10 = just released, 11 = held

+  void interpBtnPress(bool isPress) {

+    btnState = (((btnState << 1) + isPress) & 3);

+  };

+  int8_t   coordRow = 0;        // hex coordinates

+  int8_t   coordCol = 0;        // hex coordinates

+  uint32_t timePressed = 0;     // timecode of last press

+  uint32_t LEDcolorAnim = 0;    // calculate it once and store value, to make LED playback snappier 

+  uint32_t LEDcolorPlay = 0;    // calculate it once and store value, to make LED playback snappier

+  uint32_t LEDcolorOn = 0;      // calculate it once and store value, to make LED playback snappier

+  uint32_t LEDcolorOff = 0;     // calculate it once and store value, to make LED playback snappier

+  bool     animate = 0;         // hex is flagged as part of the animation in this frame, helps make animations smoother

+  int16_t  stepsFromC = 0;      // number of steps from C4 (semitones in 12EDO; microtones if >12EDO)

+  bool     isCmd = 0;           // 0 if it's a MIDI note; 1 if it's a MIDI control cmd

+  bool     inScale = 0;         // 0 if it's not in the selected scale; 1 if it is

+  byte     note = UNUSED_NOTE;  // MIDI note or control parameter corresponding to this hex

+  int16_t  bend = 0;            // in microtonal mode, the pitch bend for this note needed to be tuned correctly

+  byte     channel = 0;         // what MIDI channel this note is playing on

+  float    frequency = 0.0;     // what frequency to ring on the buzzer

+};

+

+class wheelDef {

+public:

+  bool alternateMode; // two ways to control

+  bool isSticky;      // TRUE if you leave value unchanged when no buttons pressed

+  byte* topBtn;       // pointer to the key Status of the button you use as this button

+  byte* midBtn;

+  byte* botBtn;

+  int16_t minValue;

+  int16_t maxValue;

+  int* stepValue; // this can be changed via GEM menu

+  int16_t defValue; // snapback value

+  int16_t curValue;

+  int16_t targetValue;

+  uint32_t timeLastChanged;

+  void setTargetValue() {

+    if (alternateMode) {

+      if (*midBtn >> 1) { // middle button toggles target (0) vs. step (1) mode

+        int16_t temp = curValue;

+            if (*topBtn == 1)     {temp += *stepValue;}; // tap button

+            if (*botBtn == 1)     {temp -= *stepValue;}; // tap button

+            if (temp > maxValue)  {temp  = maxValue;} 

+        else if (temp <= minValue) {temp  = minValue;};

+        targetValue = temp;

+      } else {

+        switch (((*topBtn >> 1) << 1) + (*botBtn >> 1)) {

+          case 0b10:   targetValue = maxValue;     break;

+          case 0b11:   targetValue = defValue;     break;

+          case 0b01:   targetValue = minValue;     break;

+          default:     targetValue = curValue;     break;

+        };

+      };

+    } else {

+      switch (((*topBtn >> 1) << 2) + ((*midBtn >> 1) << 1) + (*botBtn >> 1)) {

+        case 0b100:  targetValue = maxValue;                         break;

+        case 0b110:  targetValue = (3 * maxValue + minValue) / 4;    break;

+        case 0b010:

+        case 0b111:

+        case 0b101:  targetValue = (maxValue + minValue) / 2;        break;

+        case 0b011:  targetValue = (maxValue + 3 * minValue) / 4;    break;

+        case 0b001:  targetValue = minValue;                         break;

+        case 0b000:  targetValue = (isSticky ? curValue : defValue); break;

+        default: break;

+      };

+    }

+  };

+  bool updateValue(uint32_t givenTime) {

+    int16_t temp = targetValue - curValue;

+    if (temp != 0) {

+      if ((givenTime - timeLastChanged) >= CC_MSG_COOLDOWN_MICROSECONDS ) {

+        timeLastChanged = givenTime;

+        if (abs(temp) < *stepValue) {

+          curValue = targetValue;

+        } else {

+          curValue = curValue + (*stepValue * (temp / abs(temp)));

+        };

+        return 1;

+      } else {

+        return 0;

+      };

+    } else {

+      return 0;

+    };

+  };   

+};

+// back button

+

+class scaleDef {

+public:

+  std::string name;

+  byte tuning;

+  byte pattern[MAX_SCALE_DIVISIONS];

+};

+

+// this class should only be touched by the 2nd core

+class oscillator {

+public:

+  uint16_t increment = 0;

+  uint16_t counter = 0;

+};
\ No newline at end of file