sneakthief Posted February 3, 2013 Report Share Posted February 3, 2013 (edited) 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; } Edited February 3, 2013 by sneakthief Quote Link to comment Share on other sites More sharing options...
TK. Posted February 3, 2013 Report Share Posted February 3, 2013 Hi, it would be important to know, which parameters you are using exactly. Such as sMin, sMax, sFrom, sTo, sFactor Nest Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
sneakthief Posted February 3, 2013 Author Report Share Posted February 3, 2013 sFrom: 0 sTo: 127 sFactor: 1 My accelerometer (ADXL335) puts out 0-3V. The closest I can get to midi CC's that don't always roll over is this: sMin: 3 sMax: 98 But this setting still gives occasional integer rollovers from 0 to 127. - If sMin > 4, the midi CC goes *always* rolls from 0 to 127, etc. as the accelerometer voltage approaches 0V. - If sMin < 3, I can't reach anything under a midi CC value of 10 It makes no difference if it's inverted or not - I get the same problem. Isn't there some way here to prevent an int from rolling over? Quote Link to comment Share on other sites More sharing options...
TK. Posted February 3, 2013 Report Share Posted February 3, 2013 Ok, I see the problem - the factor is too low (actually it's not a factor, but a divider which has to scale down the 10bit value into the 7bit range). But apart from this configuration issue, it also makes sense to add a proper saturation. So, here are the steps: change: unsigned char value_7bit = 0; to: unsigned int value_7bit = 0; This ensures, that a rollover can be detected properly. Before the ACMath_Scale call, write: if( value_7bit > 127 ) value_7bit = 127; This ensures that the conversion value is within the 0..127 range before it will be scaled. Nevertheless, increase the "factor", otherwise the sensor will saturate to 127 quickly. Best Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
sneakthief Posted February 4, 2013 Author Report Share Posted February 4, 2013 (edited) Perfect - I'm going to experiment with this! My first experiments with the "factor" were probably negative because my sensor became a lot more sluggish when I used higher factors, but I'll see what happens when I stick with a higher factor and adjust the other parameters around it. Wie immer, vielen Dank - ich schaetze dieses ganzen MIDIbox Projekt sehr. Edited February 4, 2013 by sneakthief Quote Link to comment Share on other sites More sharing options...
sneakthief Posted February 4, 2013 Author Report Share Posted February 4, 2013 1. Your suggestion worked perfectly: if( value_7bit > 127 ) value_7bit = 127; 2. Re. "factor is too low": anything other than 1 made things worse and prevented the full midi CC range. If I use factor 2, then I can't access half of the cc range, regardless of what sMin or sMax are. I don't find that it gets saturated too quickly either. 3. Regardless of the factor, the resolution is bad over the whole range of the sensor. As I move the sensor over its 180 degrees of motion, I get midi CC jumps of 7 or 10 between values, even when moving it very slowly. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.