 # Adding Pitch bend to Midi2CV- right approach?

Hi everyone.
Im trying to add pitch-bend to a great Midi to CV converter. The complete project can be found here:
http://registeringdomainnamesismorefunthandoingrealwork.com/blogs/?tag=arduino

The sketch responds to SysEx transpose commands (2 octaves) so I thought that I could copy and modify that to have the CVPitch respond to bends. So here is pretty much the meat of the sketch with what I have so far (my additions are noted by the “pitchbend” comments):

``````void playNote(int note_, int velocity) {
unsigned int note = note_;
unsigned int voltage = 0;
if ((note >= 12) && (note < 24)) {
////Serial.println("note >= 12 && note < 24");
voltage = (voltage1)*((note - 12)/12.0);
}
else if ((note >= 24) && (note < 36)) {
////Serial.println("note >= 24 && note < 36");
voltage = (voltage2 - voltage1)*((note - 24)/12.0) + voltage1;
}
else if ((note >= 36) && (note < 48)) {
////Serial.println("note >= 36 && note < 48");
voltage = (voltage3 - voltage2)*((note - 36)/12.0) + voltage2;
}
else if ((note >= 48) && (note < 60)) {
////Serial.println("note >= 48 && note < 60");
voltage = (voltage4 - voltage3)*((note - 48)/12.0) + voltage3;
}
else if ((note >= 60) && (note < 72)) {
////Serial.println("note >= 60 && note < 72");
voltage = (voltage5 - voltage4)*((note - 60)/12.0) + voltage4;
}
noteOn = true;
if ((velocity >= 1) && (velocity < 64)) { //normal note
write_dac(WRITE_UPDATE_N, ACC, 0);
write_dac(WRITE_UPDATE_N, CV, voltage);
write_dac(WRITE_UPDATE_N, GATE, 65535);
//Serial.print("cv = ");
//Serial.print(voltage);
//Serial.println(", accent = OFF");
}
else if (velocity >= 64) { //accent
write_dac(WRITE_UPDATE_N, ACC, 65535);
write_dac(WRITE_UPDATE_N, CV, voltage);
write_dac(WRITE_UPDATE_N, GATE, 65535);
//Serial.print("cv = ");
//Serial.print(voltage);
//Serial.println(", accent = ON");
}
}

void stopNote(int note, int velocity) {
//Serial.println("Note off, GATE = 0");
write_dac(WRITE_UPDATE_N, GATE, 0);
noteOn = false;
}

void cc(int note_, int velocity_) {
write_dac(SETUP_INTERNAL_REGISTER, 0, 1);
unsigned int note = note_;
unsigned int velocity = velocity_; //you wouldn't have to convert the ints if you used
//something other than -1 to indicate they were empty,
//just keep them as bytes through out and use 128 as
//empty for MSB and LSB data byte
if (note == 4) {
if (velocity >= 64) {
write_dac(SETUP_INTERNAL_REGISTER, 0, 1);
//Serial.println("INTERNAL REGISTER ON");
}
else {
write_dac(SETUP_INTERNAL_REGISTER, 0, 0);
//Serial.println("INTERNAL REGISTER OFF");
}
}
else if (note == 1) {
unsigned int voltage = 65535*velocity/127.0;
write_dac(WRITE_UPDATE_N, 3, voltage);
//Serial.print("OUTPUT 3 = ");
//Serial.println(voltage);
}
else if (note == 14) {
unsigned int voltage = 65535*velocity/127.0;
write_dac(WRITE_UPDATE_N, 4, voltage);
//Serial.print("OUTPUT 4 = ");
//Serial.println(voltage);
}
else if (note == 20) {
unsigned int voltage = 65535*velocity/127.0;
write_dac(WRITE_UPDATE_N, 5, voltage);
//Serial.print("OUTPUT 5 = ");
//Serial.println(voltage);
}
else if (note == 21) {
unsigned int voltage = 65535*velocity/127.0;
write_dac(WRITE_UPDATE_N, 6, voltage);
//Serial.print("OUTPUT 6 = ");
//Serial.println(voltage);
}
else if (note == 22) {
unsigned int voltage = 65535*velocity/127.0;
write_dac(WRITE_UPDATE_N, 7, voltage);
//Serial.print("OUTPUT 7 = ");
//Serial.println(voltage);
}
}

void loop() {
if (Serial.available() > 0) {
//recieved something so note time for working out if the RX Led should flash
lastBonk = timer0_millis;
// read the incoming byte:
incomingByte = Serial.read();
if ((incomingByte == 144) &! sysex) {
//incoming note on
action = 1;
}
else if ((incomingByte == 128) &! sysex) {
//incoming note off
action = 2;
}
else if ((incomingByte == 176) &! sysex) {
action = 3;
}
else if ((incomingByte == 240) &! sysex) {
action = 4;
sysex = true;
//Serial.println("incoming sysex");
}
else if ((incomingByte == 247) && sysex) {
sysex = false;
//Serial.println("sysex finished");
}
else if ((incomingByte == 224) &! sysex) {  //pitchbend
action = 5;
}

else if ((action == 1) && (note == -1)) {
note = incomingByte;
}
else if ((action == 1) && (note != -1)) {
velocity = incomingByte;
//Serial.print("note on 144 ");
//Serial.print(note, DEC);
//Serial.print(" ");
//Serial.println(velocity, DEC);
if (velocity == 0) {
stopNote(note,velocity);
}
else {
playNote(note,velocity);
}
action = 0;
note = -1;
velocity = -1;
}
else if ((action == 2) && (note == -1)) {
note = incomingByte;
}
else if ((action == 2) && (note != -1)) {
velocity = incomingByte;
//Serial.print("note off 128 ");
//Serial.print(note, DEC);
//Serial.print(" ");
//Serial.println(velocity, DEC);
stopNote(note,velocity);
action = 0;
note = -1;
velocity = -1;
}
else if ((action == 3) && (note == -1)) {
note = incomingByte;
}
else if ((action == 3) && (note != -1)) {
velocity = incomingByte;
//Serial.print("cc ");
//Serial.print(note, DEC);
//Serial.print(" ");
//Serial.println(velocity, DEC);
cc(note,velocity);
action = 0;
note = -1;
velocity = -1;
}
else if ((action == 4) && (note == -1)) {
note = incomingByte;
}
else if ((action == 4) && (note != -1) && (velocity == -1)) {
velocity = incomingByte;
}
else if ((action == 4) && (note != -1) && (velocity != -1) && (extra1 == -1)) {
extra1 = incomingByte;
}
else if ((action == 4) && (note != -1) && (velocity != -1) && (extra1 != -1) && (extra2 == -1)) {
extra2 = incomingByte;
//Serial.print("sysex: ");
//Serial.print(note);
//Serial.print(" ");
//Serial.print(velocity);
//Serial.print(" ");
//Serial.print(extra1);
//Serial.print(" ");
//Serial.println(extra2);
switch (note) {
case 1:
voltage1 = velocity*512 + extra1*4 + extra2;
//Serial.print("voltage1 = ");
//Serial.println(voltage1);
break;
case 2:
voltage2 = velocity*512 + extra1*4 + extra2;
//Serial.print("voltage2 = ");
//Serial.println(voltage2);
break;
case 3:
voltage3 = velocity*512 + extra1*4 + extra2;
//Serial.print("voltage3 = ");
//Serial.println(voltage3);
break;
case 4:
voltage4 = velocity*512 + extra1*4 + extra2;
//Serial.print("voltage4 = ");
//Serial.println(voltage4);
break;
case 5:
voltage5 = 65535 + velocity*512 + extra1*4 + extra2;
//Serial.print("voltage5 = ");
//Serial.println(voltage5);
break;
}
action = 0;
note = -1;
velocity = -1;
extra1 = -1;
extra2 = -1;
}
}  /////////////////////pitchbend//////////////////////
else if ((action == 5) && (note == -1)) {
note = incomingByte;
}
else if ((action == 5) && (note != -1) && (velocity == -1)) {
velocity = incomingByte;
}
else if ((action == 5) && (note != -1) && (velocity != -1) && (extra1 == -1)) {
extra1 = incomingByte;
}
else if ((action == 5) && (note != -1) && (velocity != -1) && (extra1 != -1) && (extra2 == -1)) {
extra2 = incomingByte;
//Serial.print("sysex: ");
//Serial.print(note);
//Serial.print(" ");
//Serial.print(velocity);
//Serial.print(" ");
//Serial.print(extra1);
//Serial.print(" ");
//Serial.println(extra2);
switch (note) {
case 1:
voltage1 = velocity*512 + extra1*4 + extra2;
//Serial.print("voltage1 = ");
//Serial.println(voltage1);
break;
case 2:
voltage2 = velocity*512 + extra1*4 + extra2;
//Serial.print("voltage2 = ");
//Serial.println(voltage2);
break;
case 3:
voltage3 = velocity*512 + extra1*4 + extra2;
//Serial.print("voltage3 = ");
//Serial.println(voltage3);
break;
case 4:
voltage4 = velocity*512 + extra1*4 + extra2;
//Serial.print("voltage4 = ");
//Serial.println(voltage4);
break;
case 5:
voltage5 = 65535 + velocity*512 + extra1*4 + extra2;
//Serial.print("voltage5 = ");
//Serial.println(voltage5);
break;
}
action = 0;
note = -1;
velocity = -1;
extra1 = -1;
extra2 = -1;
}
}
``````

So this kinda works, - CV out responds to bends but its like the transpose function, pitch changes are not in real time but apply to the next note triggered - Also the tone of the note played is pretty glitchy. Getting it this far represents a huge milestone for me and my understanding of midi but it obviously not what I want.

(...ran out of room)

I added a new action (action=5)for when Ch1 Pitchbend data is received (224). And then like action 4 (sysex transpose function) I use the following data bits to modify the "volages" used to calculate the pitch CVout. Following the foramt of the rest of the sketch- After the midi pitchbend command is sent the second is "note" and then "velocity" "Extra1 and 2" would follow... As I type this I am realizing that after 244 is sent,"note" would be lsb, and "velocity" is msb, -not extra1 and extra2 as I had thought, right? So do I just need to figure out the correct way to calculate the pitch shift from "note" and "velocity"? This is all really just a stab in the dark and I could really use some wise words right now to guide me. So am I on the right track or is this approach completely off the mark? Any thoughts or suggestions are greatly appreciated. (BTW Sorry if this is in the wrong forum)

(bump) Not much progress. I tried out some other things- exchanging extra1&2 for "note & velocity" It didntnt work. Copying the transpose functions seems to be the closest to working -but again it is not in real time. Please any suggestions, anyone?