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 1. LED abstraction code
4. Refactor note play behavior into module
5. Refactor CV behavior into module 5. Refactor CV behavior into module
6. 9dof sensor code 6. 9dof sensor code
7. Alternate fingerings 7. Alternate fingerings
8. Encoder midi 8. Encoder midi
- Lever mode: pb - Lever mode: pb
- Breath mode: relative
- Breath suck control? - Breath suck control?
- -

View file

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

View file

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

View file

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

View file

@ -6,7 +6,36 @@
void singleLED(int n, int color) { 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){ 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){ void ledHalfMeter(int n, byte indicatedValue, int color){
@ -32,9 +61,15 @@ void statusLedFlip() {
} }
void statusLedFlash(uint16_t delayTime) { void statusLedFlash(uint16_t delayTime) {
for (int i = 0; i < 8; i++) {
ledStrip.setPixel(i, 0x000400);
}
ledStrip.show();
statusLedOff(); statusLedOff();
delay(delayTime/2); delay(delayTime/2);
statusLedOn(); statusLedOn();
ledStrip.clear();
ledStrip.show();
delay(delayTime/2); delay(delayTime/2);
} }
@ -44,6 +79,5 @@ void statusLedBlink() {
} }
void updateSensorLEDs(instrument_state_t &state) { void updateSensorLEDs(instrument_state_t &state) {
ledHalfMeter(1, state.breathCCVal, 0x00FF00); ledFullMeter(state.breathCCVal, 0x0000FF);
ledQuarterMeter(3, state.biteVal, 0x0000FF);
} }

View file

@ -941,7 +941,6 @@ private:
std::array<AdjustValue, 9> adjustValues = { { std::array<AdjustValue, 9> adjustValues = { {
{"BREATH", &instrument_state_t::breathSignal, &calibration_t::breathThrValOffset, &calibration_t::breathMaxValOffset, {"BREATH", &instrument_state_t::breathSignal, &calibration_t::breathThrValOffset, &calibration_t::breathMaxValOffset,
BREATH_LO_LIMIT, BREATH_HI_LIMIT, &instrument_state_t::breathZero}, 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, {"BR ALT", &instrument_state_t::breathAltSignal, &calibration_t::breathAltThrValOffset, &calibration_t::breathAltMaxValOffset,
BREATH_LO_LIMIT, BREATH_HI_LIMIT, &instrument_state_t::breathAltZero}, 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}, {"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<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" } }); PresetValueMenu<1, uint8_t> velocityMenu("VELOCITY", &preset_t::fixedVelocity, 0, 127, true, { { "DYN" } });
CurveValueMenu<0, uint8_t> curveMenu("CURVE", &preset_t::breathCurve, 0, 12); 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> 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<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<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> trill3Menu("TRILL3", &preset_t::trill3_interval, 3, 4, true, {});
PresetValueMenu<0, int8_t> cvTuneMenu("CV Tune", &preset_t::cvTune, -100, 100, false, {}); 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, {}); 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(); writePresets();
}); });
std::array<MenuScreen *const, 9> breathMenuEntries = { std::array<MenuScreen *const, 11> breathMenuEntries = {
&breathModeMenu, &breathModeMenu,
&breathCCMenu, &breathCCMenu,
&velocityMenu, &velocityMenu,
@ -1059,8 +1060,10 @@ std::array<MenuScreen *const, 9> breathMenuEntries = {
&breathIntervalMenu, &breathIntervalMenu,
&filterMenu, &filterMenu,
&spikeFilterMenu, &spikeFilterMenu,
&spikeOnFactorMenu,
&spikeOffFactorMenu,
}; };
SubMenu<9> breathMenu("BR SETUP", breathMenuEntries); SubMenu<11> breathMenu("BR SETUP", breathMenuEntries);
const std::array<MenuScreen *const, 13> controlMenuEntries = { const std::array<MenuScreen *const, 13> controlMenuEntries = {
&fingeringMenu, &fingeringMenu,

View file

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

View file

@ -5,7 +5,7 @@
#include "globals.h" #include "globals.h"
#define EEPROM_VERSION 3 #define EEPROM_VERSION 4
#define EEPROM_VERSION_ADDR 0 #define EEPROM_VERSION_ADDR 0
#define SETTINGS_OFFSET 2 #define SETTINGS_OFFSET 2
#define PRESET_MAX_SIZE 128 // Leave extra space for future settings #define PRESET_MAX_SIZE 128 // Leave extra space for future settings
@ -35,8 +35,7 @@ struct calibration_t {
int16_t extraThrVal = 850; int16_t extraThrVal = 850;
int16_t extraMaxVal = 1000; int16_t extraMaxVal = 1000;
int16_t ctouchThrVal = 900; int16_t ctouchThrVal = 900;
int16_t spikeThrVal= 25; uint8_t _reserved[24];
uint8_t _reserved[22];
}; };
static_assert(sizeof(calibration_t) == CALIBRATION_MAX_SIZE, "calibration data wrong size"); 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 breathFilterFreq = 20;
uint8_t spikeFilterFreq = 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"); 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 // send midi cc
midiSendControlChange(state.currentPreset->breathCC, breathCCval); 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 // send aftertouch
midiSendAfterTouch(breathCCval); midiSendAfterTouch(breathCCval);
} }
@ -245,6 +247,7 @@ int breath() {
oldbreathhires = breathCCvalHires; oldbreathhires = breathCCvalHires;
state.instrument->breathCCVal = breathCCval;
return breathCCval; return breathCCval;
} }
@ -790,16 +793,6 @@ void sendCCs() {
void runStateMachine() { void runStateMachine() {
static unsigned long breath_on_time = 0L; // Time when breath sensor value went over the ON threshold 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 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()); int fingeredNote = noteValueCheck(readSwitches() + readOctave());
if (state.mainState == NOTE_OFF) { if (state.mainState == NOTE_OFF) {
handleOffStateActions(); handleOffStateActions();
@ -823,10 +816,7 @@ void runStateMachine() {
state.mainState = NOTE_OFF; state.mainState = NOTE_OFF;
} }
} else if (state.mainState == NOTE_ON) { } else if (state.mainState == NOTE_ON) {
if (state.currentPreset->spikeFilterFreq && instrument.spikeSignal < -calibration.spikeThrVal) { if (instrument.breathSignal < instrument.breathThrVal) {
midiSendNoteOff(instrument.activeNote); // send Note Off message
state.mainState = SPIKE_HOLD;
} else if (instrument.breathSignal < instrument.breathThrVal) {
// Value has fallen below threshold - turn the note off // Value has fallen below threshold - turn the note off
midiSendNoteOff(instrument.activeNote); // send Note Off message midiSendNoteOff(instrument.activeNote); // send Note Off message
instrument.breathSignal = 0; instrument.breathSignal = 0;
@ -842,14 +832,6 @@ void runStateMachine() {
instrument.activeNote = fingeredNote; 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 //_______________________________________________________________________________________________ MAIN LOOP
void loop() { void loop() {
static unsigned long lastUpdate = millis();
static unsigned long pixelUpdateTime = 0; static unsigned long pixelUpdateTime = 0;
static const unsigned long pixelUpdateInterval = 80; 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 in config mgmt loop, do that and nothing else
if (configManagementMode) { if (configManagementMode) {
@ -922,9 +908,32 @@ void loop() {
return; 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.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(); runStateMachine();
sendCCs(); sendCCs();