Added better support for ACC mode

This commit is contained in:
Brian Hrebec 2024-11-08 22:29:39 -06:00
parent b401b34bb4
commit e3c91fa6ee
5 changed files with 118 additions and 47 deletions

View file

@ -217,12 +217,36 @@ int patchLimit(int value) {
int breath() {
static int oldbreath = 0;
static unsigned int oldbreathhires = 0;
static int oldbreathhires = 0;
int breathCCval, breathCCvalFine;
unsigned int breathCCvalHires;
breathCCvalHires = breathCurve(mapConstrain(instrument.breathSignal, instrument.breathBaseline, instrument.breathMaxVal, 0, 16383));
breathCCvalHires = breathCCFilter.input(breathCCvalHires);
int breathCCvalHires;
if (state.currentPreset->breathMode == BREATH_ACC || state.currentPreset->breathMode == BREATH_ACC_AT) {
int diff = instrument.breathSignal - instrument.breathZero;
if (instrument.mode == MODE_DEBUG) {
Serial.print(">accdiff:");
Serial.println(diff);
}
if (abs(diff) > calibration.breathThrValOffset) {
if (diff > 0) {
breathCCvalHires = breathCurve(mapConstrain(diff, calibration.breathThrValOffset, calibration.breathMaxValOffset, 0, 16383));
} else {
breathCCvalHires = -breathCurve(mapConstrain(-diff, calibration.breathThrValOffset, calibration.breathMaxValOffset, 0, 16383));
}
// breathCCvalHires = breathCCFilter.input(breathCCvalHires);
if (instrument.mode == MODE_DEBUG) {
Serial.print(">accdelta:");
Serial.println(breathCCvalHires);
}
breathCCvalHires = constrain(oldbreathhires + breathCCvalHires / 4, 0, 16383);
} else {
breathCCvalHires = oldbreathhires;
}
} else {
breathCCvalHires = breathCurve(mapConstrain(instrument.breathSignal, instrument.breathBaseline, instrument.breathMaxVal, 0, 16383));
breathCCvalHires = breathCCFilter.input(breathCCvalHires);
}
breathCCval = (breathCCvalHires >> 7) & 0x007F;
breathCCvalFine = breathCCvalHires & 0x007F;
if (breathCCval != oldbreath) { // only send midi data if breath has changed from previous value
@ -240,7 +264,7 @@ int breath() {
}
if (breathCCvalHires != oldbreathhires &&
(state.currentPreset->breathMode == BreathMode::BREATH_LSB || state.currentPreset->breathMode == BreathMode::BREATH_LSB_AT)) {
(state.currentPreset->breathMode == BreathMode::BREATH_LSB || state.currentPreset->breathMode == BreathMode::BREATH_LSB_AT|| state.currentPreset->breathMode == BreathMode::BREATH_ACC)) {
midiSendControlChange(state.currentPreset->breathCC + 32, breathCCvalFine);
}
@ -396,7 +420,7 @@ void portamento_() {
void sendCC() {
if (ExtraControl::CC == state.currentPreset->biteControl) {
int biteVal = mapConstrain(instrument.biteSignal, calibration.biteThrVal, calibration.biteMaxVal, 0, 127);
int biteVal = mapConstrain(instrument.biteSignal, calibration.biteThrVal, calibration.biteMaxVal, 127, 0);
if (biteVal != instrument.biteVal) {
midiSendControlChange(state.currentPreset->biteCC, biteVal);
@ -413,14 +437,13 @@ void sendCC() {
instrument.extraVal = extraVal;
}
int leverVal = mapConstrain(instrument.leverSignal, calibration.leverMinVal, calibration.leverMaxVal, 0, 127);
if (ExtraControl::CC == state.currentPreset->leverControl) {
int leverVal = mapConstrain(instrument.leverSignal, calibration.leverMinVal, calibration.leverMaxVal, 0, 127);
if (leverVal != instrument.leverVal) {
midiSendControlChange(state.currentPreset->leverCC, leverVal);
}
instrument.leverVal = leverVal;
}
instrument.leverVal = leverVal;
if (ExtraControl::CC == state.currentPreset->pbControl) {
int pbVal = mapConstrain(instrument.pbSignal, calibration.pbMinVal, calibration.pbMaxVal, 0, 127);
@ -778,20 +801,42 @@ void readSwitches() {
lastOctave = fingeredOctave;
}
void noteOn(int fingeredNote, int pressureSensor, int initial_breath_value) {
// Yes, so calculate MIDI note and velocity, then send a note on event
// We should be at tonguing peak, so set velocity based on current pressureSensor value unless fixed velocity is set
instrument.breathSignal = constrain(max(pressureSensor, initial_breath_value), instrument.breathBaseline, instrument.breathMaxVal);
byte velocitySend;
if (!state.currentPreset->fixedVelocity) {
unsigned int breathValHires = breathCurve(mapConstrain(instrument.breathSignal, instrument.breathBaseline, instrument.breathMaxVal, 0, 16383));
velocitySend = (breathValHires >> 7) & 0x007F;
velocitySend = constrain(velocitySend + velocitySend * .1 * state.currentPreset->velBias, 1, 127);
} else {
velocitySend = state.currentPreset->fixedVelocity;
uint8_t controlVel() {
uint8_t velocity = 0;
if (ExtraControl::VELOCITY_RETRIGGER == state.currentPreset->biteControl) {
velocity = mapConstrain(instrument.biteSignal, calibration.biteThrVal, calibration.biteMaxVal, 127, 1);
}
midiSendNoteOn(fingeredNote, velocitySend); // send Note Off message
if (ExtraControl::VELOCITY_RETRIGGER == state.currentPreset->leverControl) {
velocity = mapConstrain(instrument.leverSignal, calibration.leverMinVal, calibration.leverMaxVal, 1, 127);
}
if (ExtraControl::VELOCITY_RETRIGGER == state.currentPreset->pbControl) {
velocity = mapConstrain(instrument.pbSignal, calibration.pbMinVal, calibration.pbMaxVal, 1, 127);
}
return velocity;
}
uint8_t breathVel() {
// Set velocity based on current pressureSensor value unless fixed velocity is set
int velocitySend;
if (state.currentPreset->fixedVelocity) {
return state.currentPreset->fixedVelocity;
}
if (state.currentPreset->noteMode == LEVER_TRIGGER) {
return instrument.leverVal;
}
unsigned int breathValHires = breathCurve(mapConstrain(instrument.breathSignal, instrument.breathBaseline, instrument.breathMaxVal, 0, 16383));
velocitySend = (breathValHires >> 7) & 0x007F;
velocitySend = constrain(velocitySend + velocitySend * .1 * state.currentPreset->velBias, 1, 127);
return velocitySend;
}
void noteOn(int fingeredNote) {
midiSendNoteOn(fingeredNote, breathVel());
}
/**
@ -803,15 +848,20 @@ void changeNote(int fingeredNote, int activeNote, int fingeredNote2, int activeN
return;
}
int velocity = controlVel();
if (!velocity) {
velocity = breathVel();
}
// Player has moved to a new fingering while still blowing.
// Send a note off for the current note and a note on for
// the new note.
if (fingeredNote != activeNote && fingeredNote != activeNote2) {
noteOn(fingeredNote, instrument.breathSignal, 0);
midiSendNoteOn(fingeredNote, velocity);
}
if (fingeredNote2 != fingeredNote && fingeredNote2 != activeNote && fingeredNote2 != activeNote2) {
noteOn(fingeredNote2, instrument.breathSignal, 0);
midiSendNoteOn(fingeredNote2, velocity);
}
delayMicroseconds(2000); // delay for midi recording fix
@ -896,6 +946,11 @@ void handleCCs() {
}
}
int adjustRetriggerVel(int initialVel) {
int vel = initialVel;
}
/**
* Read the breath sensors according to the active mode
*/
@ -906,14 +961,7 @@ void readBreath() {
int16_t breathAltSignal = constrain(readAltPressure(), BREATH_LO_LIMIT, BREATH_HI_LIMIT) + instrument.breathAltZeroOffset;
int16_t spikeSignal = constrain(readSpikePressure(), -SPIKE_HI_LIMIT, SPIKE_HI_LIMIT);
int16_t diffSignal = breathAltSignal - breathSignal;
if (state.currentPreset->breathMode == BREATH_ACC || state.currentPreset->breathMode == BREATH_ACC_AT) {
int delta = breathSignal - instrument.breathZero;
if (abs(delta) > state.calibration->breathThrValOffset) {
instrument.breathSignal = constrain(instrument.breathSignal + delta / 15, instrument.breathZero, instrument.breathMaxVal);
}
} else {
instrument.breathSignal = breathSignal + diffSignal + (spikeSignal > 0 ? spikeSignal * state.currentPreset->spikeOnFactor : spikeSignal * state.currentPreset->spikeOffFactor);
}
instrument.breathSignal = breathSignal + diffSignal + (spikeSignal > 0 ? spikeSignal * state.currentPreset->spikeOnFactor : spikeSignal * state.currentPreset->spikeOffFactor);
instrument.breathAltSignal = breathAltSignal;
@ -962,23 +1010,27 @@ void readBreath() {
*/
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
bool lever_trigger = state.currentPreset->noteMode == LEVER_TRIGGER;
if (state.currentPreset->noteMode == NO_TRIGGER) {
return;
}
if (state.mainState == NOTE_OFF) {
handleOffStateActions();
if (instrument.breathSignal > instrument.breathThrVal && state.mainState == NOTE_OFF) {
bool crossed_threshold = lever_trigger ? instrument.leverVal > 0 : instrument.breathSignal > instrument.breathThrVal;
if (crossed_threshold && state.mainState == NOTE_OFF) {
// Value has risen above threshold. Move to the RISE_WAIT
// state. Record time and initial breath value.
breath_on_time = millis();
initial_breath_value = instrument.breathSignal;
state.mainState = RISE_WAIT; // Go to next state
}
} else if (state.mainState == RISE_WAIT) {
if ((instrument.breathSignal > instrument.breathMovingThrVal)) {
if ((lever_trigger ? instrument.leverVal > 0 : instrument.breathSignal > instrument.breathMovingThrVal)) {
// Has enough time passed for us to collect our second sample?
if ((millis() - breath_on_time > state.currentPreset->velSmpDl) || (0 == state.currentPreset->velSmpDl) || state.currentPreset->fixedVelocity) {
noteOn(instrument.fingeredNote, instrument.breathSignal, initial_breath_value);
noteOn(instrument.fingeredNote);
if (instrument.fingeredNote != instrument.fingeredNote2) {
noteOn(instrument.fingeredNote2, instrument.breathSignal, initial_breath_value);
noteOn(instrument.fingeredNote2);
}
breath(); // send breath data
state.mainState = NOTE_ON;
@ -990,7 +1042,7 @@ void runStateMachine() {
state.mainState = NOTE_OFF;
}
} else if (state.mainState == NOTE_ON) {
if (instrument.breathSignal < instrument.breathThrOffVal) {
if (lever_trigger ? instrument.leverVal <= 0 : instrument.breathSignal < instrument.breathThrOffVal) {
// Value has fallen below threshold - turn the note off
midiSendNoteOff(instrument.activeNote); // send Note Off message
if (instrument.activeNote != instrument.activeNote2) {