Modify incoming data on midi in port and to transmit them on midi out port

Hi there, i'm starting a project with Arduino.

Basically i'm gonna have an arduino with a midi in port and a midi out port

What i want is to modify incoming data with buttons linked to Arduino and transmit the modified data to the midi out port.

I found several tutorial about receveing and trasmitting data but anything that speaks about how to receive, modify and transmit them .

Is that possible? Any link to suggest?

Thanks in advance

Andrea

Is that possible?

Yes.
BUT
You have to know what you want to change.
Just read in a message, normally 3 bytes.
Store them as they come in.
Modify the bytes,
Send them out.

For example suppose you want to transform the notes by shifting them up an octave, then all you do is add 12 to the note number before retransmitting it.

ok so,

i declared the variables,
i set up the serial rate (31250)
the three bytes are read and stored
then they're wrote on the tx port.

i think the increase operation on dataByte1 should be done after the dataByte1 has been read and before the "playNote(statusByte, dataByte1, dataByte2)" message.

I tried to increase its value in different ways but, it didn't work..

I started from there:

byte statusByte, dataByte1, dataByte2;

void setup(){
    Serial.begin(31250);
  }
  void loop(){
  if(Serial.available() > 0) 
  {
    statusByte = Serial.read();
     dataByte1 = Serial.read();
      dataByte2 = Serial.read();
       playNote(statusByte, dataByte1, dataByte2);
  
 }
  }

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

Any suggestion?

Thanks..

The first problem is that your are reading 3 characters from the serial device when .available has only guaranteed you that there is one.
This will help in that case:

  if(Serial.available() >= 3)

But you aren't guaranteed that every MIDI message you receive is exactly 3 bytes. You have to look at the command byte to determine how many, if any, will follow it.

Pete

Great!!! now the expression: "dataByte1 += transposition" works!!

but.. now i have a problem with polyphony... when i send more note messages at the same time it seems note off messages don't work..

byte statusByte, dataByte1, dataByte2;

void setup(){
    Serial.begin(31250);
  }
  void loop(){
  if(Serial.available() >= 3)
  {
    statusByte = Serial.read();
     dataByte1 = Serial.read();
     dataByte1 += 24;
     
      dataByte2 = Serial.read();
       playNote(statusByte, dataByte1, dataByte2);
  
 }
  }

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

basically the code works just for one note message at a time..

they suggest me to build a state machine, what do you think about it?

You are assuming that you are getting the MIDI bytes in synchronicity. That is that the first byte is the start of a three byte MIDI message. So if you get a message shorter or longer it will throw off that program.
So yes you need a state machine to sort it out.

basically the code works just for one note message at a time.

Use a MIDI monitor to see what your code is being transformed into. Remember note off can be sent in two ways, a note on with a velocity of zero or a note off message.

what do you mean by: " a message shorter or longer"?
for what i know all the note on and note off messages are made of three bytes..
Do you mean that when i press two keys on a midi keyobard at the same time, i' m sending a 6 byte message?

what do you think about this other code? i didn't tested yet..

byte transpose = 7;

void noteon(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOn( channel, note+transpose, velocity );
}

void noteoff(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOFF( channel, note+transpose, velocity );
}

void setup() {
        MIDI.begin();
        MIDI.setHandleNoteOn(noteon);
        MIDI.setHandleNoteOff(noteoff);
}

void loop() {
        MIDI.read();
}?

Note on and note off messages are three bytes long, but there are other midi messages that are one, two, or five bytes long.
You code does not appere to include the libary include line.

i wrote a new code based on call back functions..

Problem is that Arduino doesn't transmit modified bytes....

any suggestions?
this thing is driving me mad..

thanks!

#include <MIDI.h>

byte transpose = 7;

void noteon(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOn( channel, note+transpose, velocity );
}

void noteoff(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOff( channel, note+transpose, velocity );
}

void setup() {
  
       MIDI.begin();      
        MIDI.setHandleNoteOn(noteon);
        MIDI.setHandleNoteOff(noteoff);
}

void loop() {
        MIDI.read();
}?

Ok, basically, the code miss a write function..

should i place it in void loop?

Not sure about how to use the Serial.write function in this case.

Resume: i'd like to modify incoming midi note messages on Arduino and transmit them on the tx port.
To do this i'm using callback functions.

For example: when Arduino receive a note on message on rx port , the noteon function should calledback and and the modified message transmitted on the serial port.

But, no message is sent...

I'm sure that Arduino receives midi messages. Problem is that it seems that callback doesn't work with the MIDI.sendNoteOn instruction.

It's been weeks since i started this project and i cannot figure out to solve it...

#include <MIDI.h>

byte transpose = 7;       // raise a fifth

void noteon(byte note, byte velocity, byte channel) {
    digitalWrite( 13, HIGH );         // turn on LED
    MIDI.sendNoteOn( note+transpose, velocity, channel );
}

void noteoff(byte note, byte velocity, byte channel) {
    digitalWrite( 13, LOW );          // turn off LED
    MIDI.sendNoteOff( note+transpose, velocity, channel );
}

void setup() {
        pinMode( 13, OUTPUT );                                        // LED
        MIDI.begin();      
        MIDI.setInputChannel( MIDI_CHANNEL_OMNI );      // listen to all channels
        MIDI.turnThruOff();                                                 // turn off thru mode
        MIDI.setHandleNoteOn(noteon);                             // call noteon when a note on message is received
        MIDI.setHandleNoteOff(noteoff);                            // call noteoff when a note off message is received
}

void loop() {
        MIDI.read();

}

Anyway, it seems that the library is not capable of generating new messages from within a callback... : /////

What do you think about it?

Thanks...

Hi there, i'd like to modify incoming midi note messages, and transmit them with Arduino

At first i tried to make this without Midi library but i would have to implement a full MIDI message parser so i left this way.
Then i tried to use the midi library with callback functions. Unfortunately it seems that the library is not capable of generating new messages from within a callback. (that's a shame!!!)

So, what's shoul be the next step? how should i move?

this is my last code.

#include <MIDI.h>

byte transpose = 7;       // raise a fifth

void noteon(byte note, byte velocity, byte channel) {
    digitalWrite( 13, HIGH );         // turn on LED
    MIDI.sendNoteOn( note+transpose, velocity, channel );
}

void noteoff(byte note, byte velocity, byte channel) {
    digitalWrite( 13, LOW );          // turn off LED
    MIDI.sendNoteOff( note+transpose, velocity, channel );
}

void setup() {
        pinMode( 13, OUTPUT );                                        // LED
        MIDI.begin();      
        MIDI.setInputChannel( MIDI_CHANNEL_OMNI );      // listen to all channels
        MIDI.turnThruOff();                                                 // turn off thru mode
        MIDI.setHandleNoteOn(noteon);                             // call noteon when a note on message is received
        MIDI.setHandleNoteOff(noteoff);                            // call noteoff when a note off message is received
}

void loop() {
        MIDI.read();

}

In the latest version of your code, does the LED get turned on and off when MIDI data are sent?

Pete

el_supremo:
In the latest version of your code, does the LED get turned on and off when MIDI data are sent?

Pete

yes..

Unfortunately it seems that the library is not capable of generating new messages from within a callback. (that's a shame!!!)

So in the callback function just send out the midi message by hand. That is send out three serial write bytes.

I wrote to the support for the MIDI.library.

they confirmed me that it's possible to send out midi messages from within a callback.

Maybe i found out what's the problem. I'm going to post some news tomorrow..