-->
Page 1 of 1

RTP-midi

PostPosted: Mon Nov 16, 2015 5:39 pm
by shuptuu
Hi,
I need help!
I'm trying to configure a simple rtp-midi client based on a arduino micro and an esp8266. The goal is to send midi note on and off messages to a PC running rtpMIDI. I'm ok with the rtp-midi protocol (known as Apple-midi also) and all the algorithmic. Communication between the esp and the arduino is ok too. But as I'm a newbee with arduino, I'm having problems to manipulate strings and extract rtp datas from the data sent by the esp. For exemple:
I'll receive from the esp:
+IPD,0,27:ÿÿIN »E…˜(Â6ºOM-netbook //this is an invitation rtp message
From this, I would like to extract something like:
Signature: ff ff //corresponding to ÿÿ
Command: 49 4e //corresponding to IN
Protocol version: 00 00 00 02
Initiator Token: 1a 58 fc 68 // this is not the good one, but that's an exemple
Sender SRC: 28 c2 36 ba // same thing, as an exemple
Name: OM-netbook
If somebody can give me the code to get this, that would be very helpfull. In exchange, I will post here my final sketch!
Thanks!

Re: RTP-midi

PostPosted: Tue Nov 17, 2015 6:18 pm
by shuptuu
Still searching on my side and good news, I found a way to make it running! Maybe not the start of the art, but it works!
So I'm able to connect to my PC in rtp-midi and I guess I will be able to send midi messages now without any problem.
But there is something strange: to make it running, I have to add some echo to the serial monitor (like "Serial.print(InitiatorToken[x] ,HEX);" in my code below). Without these lines, my arduino is reading boolshit from the esp and then I can't connect to my PC. I don't understand the link, except that adding these lines, it adds a delay I guess. Can somebody explain me this? An other way to do to not have this kind of problem?

my code:
Code: Select allconst uint8_t protocol[]={0,0,0,2};
const uint8_t mySSRC[]={0,0,0,0};  //SSRC for rtp, normally a random value, to modify later...
const uint8_t invitation[]={73,78}; // invitation message ff ff 49 4e  (IN)
const uint8_t accepted[]={255,255,79,75}; // accept invitation ff ff 4f 4b (OK)
const uint8_t synchro[]={67,75}; // synchro message ff ff 43 4b  (CK)

const uint8_t myempty[]={0,0,0,0}; // usefull to send 32 bits of 0

boolean resp;

unsigned long myTime;
uint8_t TimeStamp2[4];
uint8_t mybuf1[11];
uint8_t InitiatorToken[4];   // used when sending data

//-------------------------------------------------------------
void loop() {
  /* data received from the ESP */
  if (Serial1.available() > 0) {
    int ch2 = Serial1.read();
    if (ch2 == 43) {  // message starting with +
      String abc = Serial1.readStringUntil(':');
      if (abc.startsWith("IPD")){ // that's data!
        int id = abc.substring(4,5).toInt(); //
        Serial.print("Data received on id: "+String(id));
        int datalength = abc.substring(6,abc.length()).toInt();
        Serial.println(" - Message length: "+String(datalength)+"bytes");
        if (datalength>0) {
          // reading to know the command
          uint8_t command[4];
          for (int x = 0; x < 4; x++){
            command[x] = Serial1.read();
          }
          /*------------------------------------
           * command interpreter
           *-----------------------------------*/
          if (command[2] == invitation[0] && command[3] == invitation[1]) {  // Invitation
            Serial.println("=> Invitation");
            for (int x = 0; x < 4; x++){
              Serial.print(Serial1.read());  // we don't care of this 4 bytes!
            }
            Serial.print("InitiatorToken:");
            for (int x = 0; x < 4; x++){
              InitiatorToken[x] = Serial1.read();
              Serial.print(InitiatorToken[x] ,HEX);
            }
            Serial.println("");
            /*--     my answer   --*/
            Serial1.println("AT+CIPSEND="+String(id)+",22");
            Serial1.find(">");
            Serial1.write(accepted, 4);
            Serial1.write(protocol, 4);
            Serial1.write(InitiatorToken, 4);
            Serial1.write(mySSRC, 4);
            Serial1.print("OM-A1");
            Serial1.write(0);
            Serial.print("myAnswerSent...");
            resp = Serial1.find("OK\r\n");
            Serial.println(resp);
          }
         
          else if (command[2] == synchro[0] && command[3] == synchro[1]) { // Synchronisation
            for (int x = 0; x < 4; x++){
              Serial.print(Serial1.read());  // we don't care of this 4 bytes!
            }
            Serial.print("=> Synchro: count=");
            int SyncCount=Serial1.read();
            Serial.println(SyncCount);
            if (SyncCount == 0){ // this is the only one we need to answer
              for (int x = 0; x < 11; x++){
                mybuf1[x] = Serial1.read();  //we read all what we have to send back (including TimeStamp1)
                Serial.print(mybuf1[x] ,HEX);
              }
              // my TimeStamp calculation
              myTime= millis();
              TimeStamp2[0] = (int)((myTime >> 24) & 0xFF) ;
              TimeStamp2[1] = (int)((myTime >> 16) & 0xFF) ;
              TimeStamp2[2] = (int)((myTime >> 8) & 0xFF) ;
              TimeStamp2[3] = (int)(myTime & 0xFF) ;
              //--     my answer   --//
              Serial1.println("AT+CIPSEND="+String(id)+",36");
              Serial1.find(">");
              Serial1.write(command, 4);
              Serial1.write(mySSRC, 4);
              Serial1.write(1);
              Serial1.write(mybuf1, 11);
              Serial1.write(myempty, 4);
              Serial1.write(TimeStamp2, 4);
              Serial1.write(myempty, 4);
              Serial1.write(myempty, 4);
              Serial.print("myAnswerSent...");
              resp = Serial1.find("OK\r\n");
              Serial.println(resp);
            }
            else {
              Serial.println("No need to answer");
              String def = Serial1.readStringUntil('\n'); // read any remaining characters in espSerial buffer that we don't care => flush
            }
          }
          else {
            Serial.println("Command not supported...");
            String def = Serial1.readStringUntil('\n'); // read any remaining characters in espSerial buffer that we don't care => flush
          }
         
        }
      }
    }
    else {
      String abc = Serial1.readStringUntil('\n');
      Serial.println(String(ch2)+abc);
    }
  }
 


}

Re: RTP-midi

PostPosted: Thu Nov 19, 2015 4:00 am
by shuptuu
Done! It's fully working now, I'm able to send midi messages and to receive them on my PC. I fixed my last problem by adding some waits for data available on the serial port.
My issue now is that the latency is quite big, too big for playing music in realtime (moving up to 400ms).
Sure it's coming from the esp.
Will have to use an other wifi module or customize the sketch inside the esp...

Re: RTP-midi

PostPosted: Mon Sep 17, 2018 6:33 pm
by Roy Jan
Hey, I am super excited to see info about that subject,
there any chance to share the final code?