I keep banging my head against Audiocommander’s AC Sensorizer code.
This part of the code reads the 8 analog-in pins and then converts them to 7-bit MIDI cc (0-127) commands, but the problem is that sensors can cause this value to roll-over, regardless of the sensor minimum and maximum settings (sMax & sMin).
In other words, I keep getting MIDI cc’s that roll-over and go 124, 125, 126, 127, 0, 1, 2, etc. - or 3, 2, 1, 0, 127, 126, 125, etc.
How can I prevent this?
// sense range
volatile unsigned int sMin[SENSOR_NUM]; // 10-bit minimum sense (ignore below; => 7bit: 0)
volatile unsigned int sMax[SENSOR_NUM]; // 10-bit maximum sense (ignore above; => 7bit: 127)
// expand signal
volatile unsigned char sFactor[SENSOR_NUM]; // calibrated sensor factor: (sMax - sMin) / 127
// if somehow possible use 1, 2, 4, 8 or 16
// to use fastest bit-shifting algorithm
// otherwise a complex multi-cycle division occurs
volatile unsigned char sFrom[SENSOR_NUM]; // scale to target min value (e.g. 0)
volatile unsigned char sTo[SENSOR_NUM]; // scale to target max value (e.g. 127)
/////////////////////////////////////////////////////////////////////////////
// This function reads the 10-bit value from <pin> and sends a 7-bit inter-
// polated value. The sensors must be calibrated (with autoSensing) to
// obtain good sensor measurements.
/////////////////////////////////////////////////////////////////////////////
unsigned char ACSensorizer_Sensorize(unsigned char pin, unsigned int pin_value) __wparam
{
// temp values
unsigned char value_7bit = 0;
unsigned int value_10bit = 0;
// abort if OFF (disabled)
if(! sensor[pin].enabled) { return SRETURN_ABORT; }
// abort if pedal enabled & pedal is not down (=1)
if((sensor[pin].pedalMode >= PEDAL_FILTER) && (sensorizer.pedalUp)) { return SRETURN_ABORT; }
// abort if below sMin or above sMax
if(pin_value < sMin[pin]) {
if((sensor[pin].releaseDetect) && (lastAIN_value[pin] != 0)) {
lastAIN_value[pin] = 0;
return 0; // send 0 to mute sound on release
} else {
return SRETURN_RELEASEDETECT;
}
}
if(pin_value > sMax[pin]) { return SRETURN_ABORT; }
// expand
value_10bit = pin_value - sMin[pin];
switch(sFactor[pin]) {
case 1: value_7bit = (unsigned char) value_10bit; break;
case 2: value_7bit = (unsigned char)(value_10bit >> 1); break;
case 4: value_7bit = (unsigned char)(value_10bit >> 2); break;
case 8: value_7bit = (unsigned char)(value_10bit >> 3); break;
case 16: value_7bit = (unsigned char)(value_10bit >> 4); break;
default:
value_7bit = (unsigned char)ACMath_Divide(value_10bit, (unsigned int)sFactor[pin]);
break;
}
// scale
value_7bit = ACMath_Scale(value_7bit, sFrom[pin], sTo[pin]);
// restrict to 7 bit MIDI-values
if(value_7bit < sFrom[pin]) { return SRETURN_ABORT; }
if(value_7bit > sTo[pin]) { return SRETURN_ABORT; }
// don't send unchanged values
if(value_7bit == lastAIN_value[pin]) { return SRETURN_ABORT; }
// store last 10bit value
lastAIN_value[pin] = value_7bit;
lastAIN_10bitValue[pin] = value_10bit;
// return success
// invert
if(sensor[pin].invert) {
inverted_value = value_7bit - value_7bit - value_7bit;
value_7bit = inverted_value + 127;
}
return value_7bit;
}