diff options
Diffstat (limited to 'Classes.h')
| -rw-r--r-- | Classes.h | 158 |
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 |
