Additional br tweaking

This commit is contained in:
Brian Hrebec 2023-08-30 22:50:55 -05:00
parent 7740c09375
commit e757ebc885
9 changed files with 91 additions and 44 deletions

View file

@ -1,11 +1,9 @@
1. LED abstraction code
4. Refactor note play behavior into module
5. Refactor CV behavior into module
6. 9dof sensor code
7. Alternate fingerings
8. Encoder midi
- Lever mode: pb
- Breath mode: relative
- Breath suck control?
-

View file

@ -57,6 +57,6 @@
#define LEVER_LO_LIMIT 500
#define LEVER_HI_LIMIT 1000
#define SPIKE_LO_LIMIT 0
#define SPIKE_HI_LIMIT 100
#define SPIKE_HI_LIMIT 200
#endif

View file

@ -18,9 +18,6 @@
// A note is sounding
#define NOTE_ON 3
// We turned the note off due to a HF spike
#define SPIKE_HOLD 4
enum PinkyMode : uint8_t {
PBD = 12,
GLD = 25,
@ -54,6 +51,8 @@ enum BreathMode : uint8_t {
BREATH_LSB = 1,
BREATH_AT = 2,
BREATH_LSB_AT = 3,
BREATH_ACC = 4,
BREATH_ACC_AT = 5,
};
enum ExtraControl : uint8_t {
@ -89,7 +88,6 @@ struct instrument_state_t {
// Raw sensor signals
int16_t breathSignal = 0; // breath level (smoothed) not mapped to CC value
int16_t breathAltSignal = 0;
int16_t spikeSignal = 0; // breath level (smoothed) not mapped to CC value
int16_t biteSignal = 0; // capacitance data from bite sensor, for midi cc and threshold checks
int16_t leverSignal = 0;
int16_t pbUpSignal = 0;

View file

@ -120,9 +120,9 @@ int readKnob(uint8_t n) {
static unsigned long lastOutTime = 0;
int out = 0;
int32_t val = knobs[n].read();
if (val > (lastOut < 0) ? 3 : 4) {
if (val > ((lastOut < 0) ? 3 : 4)) {
out = val / 4;
} else if (val < (lastOut > 0) ? -3 : -4) {
} else if ((val < (lastOut > 0) ? -3 : -4)) {
out = val / 4;
}

View file

@ -6,7 +6,36 @@
void singleLED(int n, int color) {
}
// 0000 0001
// 0000 0010
// 0000 0011
// 0000 0100
// ...
// 0111 0000
// 0111 1111
// >> 4 == 0111
// 127 -> 255, 255, 255, 255, 255, 255, 255, 255
// 64 -> 255, 255, 255, 255, 0, 0, 0, 0
// 64 -> 255, 255, 255, 255, 0, 0, 0, 0
// 32 -> 255, 255, 0, 0, 0, 0, 0, 0
// 24 -> 255, 127, 0, 0, 0, 0, 0, 0
// 16 -> 255, 0, 0, 0, 0, 0, 0, 0
// 8 -> 127, 0, 0, 0, 0, 0, 0, 0
// 0 -> 0, 0, 0, 0, 0, 0, 0, 0
void ledFullMeter(byte indicatedValue, int color){
int scaledVal = indicatedValue;
ledStrip.setBrightness(1);
for (int i = 0; i < 8; i++) {
if (scaledVal > 0) {
ledStrip.setPixel(i, color);
} else {
ledStrip.setPixel(i, 0);
}
scaledVal -= 16;
}
ledStrip.show();
}
void ledHalfMeter(int n, byte indicatedValue, int color){
@ -32,9 +61,15 @@ void statusLedFlip() {
}
void statusLedFlash(uint16_t delayTime) {
for (int i = 0; i < 8; i++) {
ledStrip.setPixel(i, 0x000400);
}
ledStrip.show();
statusLedOff();
delay(delayTime/2);
statusLedOn();
ledStrip.clear();
ledStrip.show();
delay(delayTime/2);
}
@ -44,6 +79,5 @@ void statusLedBlink() {
}
void updateSensorLEDs(instrument_state_t &state) {
ledHalfMeter(1, state.breathCCVal, 0x00FF00);
ledQuarterMeter(3, state.biteVal, 0x0000FF);
ledFullMeter(state.breathCCVal, 0x0000FF);
}

View file

@ -941,7 +941,6 @@ private:
std::array<AdjustValue, 9> adjustValues = { {
{"BREATH", &instrument_state_t::breathSignal, &calibration_t::breathThrValOffset, &calibration_t::breathMaxValOffset,
BREATH_LO_LIMIT, BREATH_HI_LIMIT, &instrument_state_t::breathZero},
{"TRIGGER", &instrument_state_t::spikeSignal, &calibration_t::spikeThrVal, &calibration_t::spikeThrVal, SPIKE_LO_LIMIT, SPIKE_HI_LIMIT, NULL},
{"BR ALT", &instrument_state_t::breathAltSignal, &calibration_t::breathAltThrValOffset, &calibration_t::breathAltMaxValOffset,
BREATH_LO_LIMIT, BREATH_HI_LIMIT, &instrument_state_t::breathAltZero},
{"BITE",&instrument_state_t::biteSignal, &calibration_t::biteThrVal, &calibration_t::biteMaxVal, BITE_LO_LIMIT, BITE_HI_LIMIT, NULL},
@ -956,7 +955,7 @@ AdjustMenuScreen<9> adjustMenu("ADJUST", adjustValues);
//***********************************************************
ChoiceMenu<4, BreathMode> breathModeMenu("BR MODE", &preset_t::breathMode, { { BREATH_STD, BREATH_LSB, BREATH_AT, BREATH_LSB_AT} }, { { "STD", "LSB", "AT", "AT+" } });
ChoiceMenu<6, BreathMode> breathModeMenu("BR MODE", &preset_t::breathMode, { { BREATH_STD, BREATH_LSB, BREATH_AT, BREATH_LSB_AT, BREATH_ACC, BREATH_ACC_AT} }, { { "STD", "LSB", "AT", "AT+", "ACC", "ACC+AT" } });
PresetValueMenu<128, uint8_t> breathCCMenu("BREATH CC", &preset_t::breathCC, 0, 127, true, CC_NAMES);
PresetValueMenu<1, uint8_t> velocityMenu("VELOCITY", &preset_t::fixedVelocity, 0, 127, true, { { "DYN" } });
CurveValueMenu<0, uint8_t> curveMenu("CURVE", &preset_t::breathCurve, 0, 12);
@ -965,6 +964,8 @@ PresetValueMenu<1, uint8_t> velBiasMenu("VEL BOOST", &preset_t::velBias, 0, 30,
PresetValueMenu<0, uint8_t> breathIntervalMenu("BR INTV", &preset_t::breathInterval, 0, 30, true, {}, "ms");
PresetValueMenu<0, uint8_t> filterMenu("FILTER CT", &preset_t::breathFilterFreq, 1, 100, false, {}, "hz");
PresetValueMenu<1, uint8_t> spikeFilterMenu("FILTER TRG", &preset_t::spikeFilterFreq, 0, 100, false, {"OFF"}, "hz");
PresetValueMenu<0, int8_t> spikeOnFactorMenu("TRG ON MUL", &preset_t::spikeOnFactor, -25, 25, false, {}, "x");
PresetValueMenu<0, int8_t> spikeOffFactorMenu("TRG OFF MUL", &preset_t::spikeOffFactor, -25, 25, false, {}, "x");
PresetValueMenu<0, int8_t> trill3Menu("TRILL3", &preset_t::trill3_interval, 3, 4, true, {});
PresetValueMenu<0, int8_t> cvTuneMenu("CV Tune", &preset_t::cvTune, -100, 100, false, {});
PresetValueMenu<0, uint8_t> cvVibMenu("CV LFO", &preset_t::cvVibRate, 0, 8, false, {});
@ -1049,7 +1050,7 @@ FuncMenu saveAllPresetsMenu("SAVE PRESETS", [](state_t &state, InputState& input
writePresets();
});
std::array<MenuScreen *const, 9> breathMenuEntries = {
std::array<MenuScreen *const, 11> breathMenuEntries = {
&breathModeMenu,
&breathCCMenu,
&velocityMenu,
@ -1059,8 +1060,10 @@ std::array<MenuScreen *const, 9> breathMenuEntries = {
&breathIntervalMenu,
&filterMenu,
&spikeFilterMenu,
&spikeOnFactorMenu,
&spikeOffFactorMenu,
};
SubMenu<9> breathMenu("BR SETUP", breathMenuEntries);
SubMenu<11> breathMenu("BR SETUP", breathMenuEntries);
const std::array<MenuScreen *const, 13> controlMenuEntries = {
&fingeringMenu,

View file

@ -343,6 +343,10 @@ void readEEPROM(const bool factoryReset, calibration_t &calibration) {
presets[i].breathFilterFreq = 20;
presets[i].spikeFilterFreq = 20;
}
if (settings_version < 4) {
presets[i].spikeOnFactor = 5;
presets[i].spikeOffFactor = 5;
}
}
writePresets();

View file

@ -5,7 +5,7 @@
#include "globals.h"
#define EEPROM_VERSION 3
#define EEPROM_VERSION 4
#define EEPROM_VERSION_ADDR 0
#define SETTINGS_OFFSET 2
#define PRESET_MAX_SIZE 128 // Leave extra space for future settings
@ -35,8 +35,7 @@ struct calibration_t {
int16_t extraThrVal = 850;
int16_t extraMaxVal = 1000;
int16_t ctouchThrVal = 900;
int16_t spikeThrVal= 25;
uint8_t _reserved[22];
uint8_t _reserved[24];
};
static_assert(sizeof(calibration_t) == CALIBRATION_MAX_SIZE, "calibration data wrong size");
@ -93,8 +92,10 @@ struct preset_t {
uint8_t breathFilterFreq = 20;
uint8_t spikeFilterFreq = 20;
int8_t spikeOnFactor = 5;
int8_t spikeOffFactor = 5;
uint8_t _reserved[85];
uint8_t _reserved[83];
};
static_assert(sizeof(preset_t) == PRESET_MAX_SIZE, "preset_t must be 128 bytes");

View file

@ -231,7 +231,9 @@ int breath() {
// send midi cc
midiSendControlChange(state.currentPreset->breathCC, breathCCval);
}
if (state.currentPreset->breathMode == BreathMode::BREATH_AT || state.currentPreset->breathMode == BreathMode::BREATH_LSB_AT) {
if (state.currentPreset->breathMode == BreathMode::BREATH_AT
|| state.currentPreset->breathMode == BreathMode::BREATH_LSB_AT
|| state.currentPreset->breathMode == BreathMode::BREATH_ACC_AT) {
// send aftertouch
midiSendAfterTouch(breathCCval);
}
@ -245,6 +247,7 @@ int breath() {
oldbreathhires = breathCCvalHires;
state.instrument->breathCCVal = breathCCval;
return breathCCval;
}
@ -790,16 +793,6 @@ void sendCCs() {
void runStateMachine() {
static unsigned long breath_on_time = 0L; // Time when breath sensor value went over the ON threshold
static int initial_breath_value = 0; // The breath value at the time we observed the transition
Serial.print(">breath:");
Serial.println(instrument.breathSignal);
Serial.print(">breathThr:");
Serial.println(instrument.breathThrVal);
Serial.print(">spike:");
Serial.println(instrument.spikeSignal);
Serial.print(">note:");
Serial.println(state.mainState);
int fingeredNote = noteValueCheck(readSwitches() + readOctave());
if (state.mainState == NOTE_OFF) {
handleOffStateActions();
@ -823,10 +816,7 @@ void runStateMachine() {
state.mainState = NOTE_OFF;
}
} else if (state.mainState == NOTE_ON) {
if (state.currentPreset->spikeFilterFreq && instrument.spikeSignal < -calibration.spikeThrVal) {
midiSendNoteOff(instrument.activeNote); // send Note Off message
state.mainState = SPIKE_HOLD;
} else if (instrument.breathSignal < instrument.breathThrVal) {
if (instrument.breathSignal < instrument.breathThrVal) {
// Value has fallen below threshold - turn the note off
midiSendNoteOff(instrument.activeNote); // send Note Off message
instrument.breathSignal = 0;
@ -842,14 +832,6 @@ void runStateMachine() {
instrument.activeNote = fingeredNote;
}
}
} else if (state.mainState == SPIKE_HOLD) {
if (state.currentPreset->spikeFilterFreq && instrument.spikeSignal > calibration.spikeThrVal) {
noteOn(fingeredNote, instrument.breathSignal, initial_breath_value);
state.mainState = NOTE_ON;
instrument.activeNote = fingeredNote;
} else if ((instrument.breathSignal < instrument.breathThrVal)) {
state.mainState = NOTE_OFF;
}
}
}
@ -908,8 +890,12 @@ void setup() {
//_______________________________________________________________________________________________ MAIN LOOP
void loop() {
static unsigned long lastUpdate = millis();
static unsigned long pixelUpdateTime = 0;
static const unsigned long pixelUpdateInterval = 80;
unsigned long time = millis();
unsigned long deltaTime = time - lastUpdate;
lastUpdate = time;
// If in config mgmt loop, do that and nothing else
if (configManagementMode) {
@ -922,9 +908,32 @@ void loop() {
return;
}
instrument.breathSignal = constrain(readPressure(), BREATH_LO_LIMIT, BREATH_HI_LIMIT); // Get the filtered pressure sensor reading from analog pin A0, input from sensor MP3V5004GP
int16_t breathSignal = constrain(readPressure(), BREATH_LO_LIMIT, BREATH_HI_LIMIT); // Get the filtered pressure sensor reading from analog pin A0, input from sensor MP3V5004GP
int16_t spikeSignal = constrain(readSpikePressure(), -SPIKE_HI_LIMIT, SPIKE_HI_LIMIT);
if (state.currentPreset->breathMode == BREATH_ACC || state.currentPreset-> breathMode == BREATH_ACC_AT) {
int delta = breathSignal - instrument.breathZero;
if (abs(delta) > state.calibration->breathAltThrValOffset) {
instrument.breathSignal = constrain(instrument.breathSignal + delta / 10, instrument.breathZero, instrument.breathMaxVal);
}
} else {
instrument.breathSignal = breathSignal + (spikeSignal > 0 ? spikeSignal * state.currentPreset->spikeOnFactor : spikeSignal * state.currentPreset->spikeOffFactor);
}
instrument.breathAltSignal = constrain(readAltPressure(), BREATH_LO_LIMIT, BREATH_HI_LIMIT); // Get the filtered pressure sensor reading from analog pin A0, input from sensor MP3V5004GP
instrument.spikeSignal = constrain(readSpikePressure(), -SPIKE_HI_LIMIT, SPIKE_HI_LIMIT);
/*
Serial.print(">breathThr:");
Serial.println(instrument.breathThrVal);
Serial.print(">note:");
Serial.println(state.mainState);
Serial.print(">spike:");
Serial.println(spikeSignal);
Serial.print(">breath:");
Serial.println(breathSignal);
Serial.print(">combo:");
Serial.println(instrument.breathSignal);
*/
runStateMachine();
sendCCs();