Change MIDI channel

I have a simple MIDI keyboard that only sends messages on channel 1
I want to use it with a EHX V256 vocoder that only receives messages on channel 16

I have built a circuit with an arduino + MIDI I/O
I would like to read the incoming MIDI message, and pass it on to MIDI out, just changing the channel number.

Any suggestions to how to do this fast enough?

I have tried with this code:

byte incomingByte;


void setup(){
   Serial.begin(31250);
}
  
void loop () {
  if (Serial.available() > 0) {   // read the incoming byte:
    incomingByte = Serial.read();
    Serial.print(incomingByte, BYTE); //debugging over midi out
    
  }
}

it reads the MIDI message, and sends it to MIDI out
so the circuit works

then I tried to change the channel with:

byte statusByte, dataByte1, dataByte2;

void setup(){
    Serial.begin(31250);
  }
  
void loop(){
  if(Serial.available() > 0) {
    statusByte = Serial.read();
    if (statusByte == 0x90){
      while(Serial.available() < 1){  //wait for dataByte1 to arrive on Serial;
   }
      dataByte1 = Serial.read();
      while(Serial.available() < 1){  //wait for dataByte2 to arrive;
   }
      dataByte2 = Serial.read();
   }
   if (statusByte == 0x90){ 
    playNote(0x9F, dataByte1, dataByte2);
  }
 }
}
  

  void playNote(byte cmd , byte pitch, byte velocity){
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
  }

With this code it reads the MIDI message and changes the channel by sending 159 (note on ch.16) as the first byte
but it can not read multiple notes (polyphony) and if the key is released too fast, it will not register it to send the note off

I would really appreciate if anybody has any suggestions on how to do this
Would the MIDI.h library handle polyphony and be faster to read/write the message?

Well you could do this with the loop:-

void loop(){
  if(Serial.available() > 2) {
    statusByte = Serial.read();
    if (statusByte == 0x90){
      dataByte1 = Serial.read();
      dataByte2 = Serial.read();
      playNote(0x9F, dataByte1, dataByte2);
  }
 }
}

However I think your problem is the

 if (statusByte == 0x90){

line. If your input is using running status then you will get out of sync with the messages. Your code also ignores the note off messages, you need to convert them into note off for the new channel as well.

I think you can handle the note off situation something like this:-

void loop(){
  if(Serial.available() > 2) {
    statusByte = Serial.read();
    if (statusByte == 0x90 || statusByte == 0x80 ){
      dataByte1 = Serial.read();
      dataByte2 = Serial.read();
      playNote(statusByte | 0xf, dataByte1, dataByte2);
  }
 }
}

A MIDI command byte is easy to detect because it is the only one which has the high order bit set. Try this:

byte incomingByte;

void setup(){
   Serial.begin(31250);
}
  
void loop () {
  if (Serial.available() > 0) {   // read the incoming byte:
    incomingByte = Serial.read();
    if(incomingByte & 0x80) {
      // Command byte. Change channel to 0xf if this is NOT a system message
      if((incomingByte & 0xf0) != 0xf0)incomingByte |= 0x0f;
    }
    Serial.print(incomingByte, BYTE); //debugging over midi out
  }
}

Pete

thanks guys :slight_smile:

Pete, that was exactly the type of "bit-wizardry" I was hoping for
It worked perfect.
I have spent a while now to go through the math to understand it, so it's been a learning experience as well.

hi there!

what if i would change the second byte of the note on / note off messages?

I'm trying to compile a code for a transposition box..

thanks

Andrea

schiller:
hi there!

what if i would change the second byte of the note on / note off messages?

I'm trying to compile a code for a transposition box..

thanks

Andrea

Yes that would work, add 12 to shift up an octave.

Hello,

I have an important question:

Was this code used for a midi keyboard connected to the arduino with a MIDI cable, or using a USB cable (USB host shield)??
I also would like to change the MIDI channel of my keyboard, but it has to work with a USB cable. The USB port is only
available on the arduino ADK rev3, which would therefor be my choice.

the idea is to change the channel and send the data to my computer.

thank you for your time.

Was this code used for a midi keyboard connected to the arduino with a MIDI cable,

Yes.

he USB port is only available on the arduino ADK rev3, which would therefor be my choice.

Be aware that this is unlikely to work with a USB MIDI HID right out of the box, you will have a lot of complex code to write or find.

This thread may be cold by now - I havn't been lurking for a while.

You can do what you want using my midTemperament tuning aid application on Merry music. Just ignore the features you don't need. If you want, you can set each octave of your keyboard to a different channel!

It uses a Sparkfun midi shield, though you can make your own, and the MIDI library with callbacks. My only Arduino is a Mega 2560, but a smaller one should be OK.

For the benefit of search engines, I mention that the application uses Roland JV / XP system exclusive messages (which are well handled by the library) and allows you to microtune these synthesisers.

This is great, it effectively changes notes coming from any channel to channel 16.
How would I go about changing them to a different channel?
I tried changing one line from

if((incomingByte & 0xf0) != 0xf0)incomingByte |= 0x0f;

to

if((incomingByte & 0xf0) != 0xf0)incomingByte |= 0x0e;

thinking that it would send them all to channel 15. It kinda worked, but now any notes coming from odd numbered channels go to channel 15, while those from even numbered channels are still output to channel 16.

What am I missing?

What am I missing

You are missing reading the how to use this forum sticky thread.

It will tell you how to ask questions and also tell you to not hijack the threads or resurrect old threads without very good reason.

Now start your own thread and include more detail, and post all your code.

Sorry, I've seen so many forums where everybody groans if you start a thread that's related to a topic already being discussed. I was simply trying to help keep the place tidy and organized with like information in one place. Will do.

Sorry, I've seen so many forums where everybody groans if you start a thread that's related to a topic already being discussed.

But here we go by these rules, cunningly hidden at the start of each section How to use this forum

Hello i want to send a midi message like breath control to three channels 1, 2 and 2 in the midi output can you help a bit

I think you missed what I said in my previous reply.