ARDUINO - TRAKTOR read MIDI out message and do something

Hi all,

since there is not so much to find about the “MidiUSB.read()” function I
goin to try te get my information here.

I’m using this lib:

https://www.arduino.cc/en/Reference/MIDIUSB

I succesfully connected buttons, pots and encoders to assemble a USB midi controller to
control the traktor software.

Now I want to use the MIDI out message which traktor can send to the arduino due controller.

for example if I press play a led goes on to indicate the track is playing…

when this button is pressed the traktor software send these MIDI messages

so you can see when play is on the message " channel: 3 ; CC: modulation wheel (coarse); velocity 127" are sent to the arduino.

when play is off the message " channel: 3 ; CC: modulation wheel (coarse); velocity 127" are sent to the arduino.

so how do I need to use the read function to make the led go on and off AND make i suitable for all MIDI messages.

thanks in advance.

Jazzy

The library includes a MIDI read example. The received MIDI event is stored in a data structure (rx) and you can access its header (message type nibble and channel) and data bytes (controller and value) using rx.header, rx.byte1 and rx.byte2 respectively. (rx.byte3 is not used for a CC event.)

if((rx.header >> 4) == 2) { // channel 3 (channel 1 has value 0)
  if((rx.header & 0b1111) == 0b1011) { // control change
    if(rx.byte1 == 1) { // Modulation wheel
      digitalWrite(ledPin, rx.byte2 >> 6); // 0 >> 6 = 0 and 127 >> 6 = 1
    }
  }
}

Hope this helps! Pieter

Hi Pieter,

Thanks for the reply,

I copied your code and put it in the example but it does not seem to work...

for me this part of coding is like chinese! i see a lot of bit shifting and so on but actually I don't know what i am doing.

I need to do this for like 25 commands so i thought if i can get it for one i just need to adjust the parameters ;).

this is what I did:

/*
 * MIDIUSB_test.ino
 *
 * Created: 4/6/2015 10:47:08 AM
 * Author: gurbrinder grewal
 * Modified by Arduino LLC (2015)
 */ 

#include "MIDIUSB.h"

#define ledPin 13

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void setup() {
  pinMode(ledPin,OUTPUT);
}

// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

void loop() {
  
  midiEventPacket_t rx;

    rx = MidiUSB.read();
    
if((rx.header >> 4) == 2) { // channel 3 (channel 1 has value 0)
  if((rx.header & 0b1111) == 0b1011) { // control change
    if(rx.byte1 == 1) { // Modulation wheel
      digitalWrite(ledPin, rx.byte2 >> 6); // 0 >> 6 = 0 and 127 >> 6 = 1
    }
  }
}
}

at least now I know how the data comes in the arduino thanks for that tough!

I can't test it at the moment, but I'll try to explain the concepts, so you can experiment for yourself. First, you should read up on the MIDI protocol. Some time ago, I wrote a guide to create a MIDI controller, where I explain the basics of the protocol. You can find it here. There are some links at the bottom of the page as well. (The top of the page is not important and probably outdated.)

I swapped the order of channel and channel message nibble, this is the updated code:

1) )if((rx.header >> 4) == 0b1011) { // control change
2)  if((rx.header & 0b1111) == 2) { // channel 3 (channel 1 has value 0)
3)    if(rx.byte1 == 1) { // Modulation wheel
4)      digitalWrite(ledPin, rx.byte2 >> 6); // 0 >> 6 = 0 and 127 >> 6 = 1
      }
    }
  }

So the general notation of a control change event is 1011 cccc 0nnnnnnn 0vvvvvvv (in binary). 1011 is the first nibble (4 bits), and indicates that this message is a control change message. The second nibble of the first byte is the channel number. This ranges from 0000 (channel 1) to 1111 (channel 16). The second byte starts with a zero, followed by seven data bits: nnnnnnn is the controller number (i.e. the 'address' of the controller that will be changed). In your case, the controller is the modulation wheel, or 0000001 according to the MIDI specification. The last seven bits are the new value of the controller, from 0 to 127. The first two nibbles (=1 byte), i.e. 1011 cccc, is saved to rx.header. On line one of the code, I check if the channel message matches 1011, to be sure that the message we received is a control change message. I do this by bitshifting 4 bits to the right (>>4), so the byte 1011 cccc >> 4 = 0000 1011. On line two, I check the channel. To extract this from the header byte, I perform a bitwise and on it. 1011 cccc & 0000 1111 = 0000 cccc. (0&0=0, 0&1=0, 1&0=0, 1&1=1). Tracktor seems to use channel 3 for this message, which is represented by the number 2. (channel - 1). On line three, I check if the first data byte (0nnn nnnn) matches the controller number 1 (modulation wheel). Finally, we need to know the value, which is either 0 (button released, binary 0000 0000) or 127 (button pressed, binary 0111 1111). To translate it to 0 (released) and 1 (pressed), I just shift everything 6 places to the right to get rid of the 6 rightmost bits. So if it was 0, it'll be still zero, and if it was 0111 1111 (remove 6 rightmost 1's), it'll be 01 or just one. The we use that data (0 or 1) to turn off or on the LED.

Pieter

Thanks again Pieter for such a detailed explanation and fast reply!

I start to get the build up from a midi message (binary-wise).

I hooked up a serial monitor to see what the arduino recieves from the traktor software so I can anticipate to that.

I don't expect that you give me the complete code ;-) but maybe we are just missing out on something...

I did not have time to test your update code I will do that ASAP. It could be that my controller number is changed but that i just have to change then.

|500x297

Thank you so much for all the help soo far, once i tried some bits of (your) code I will come back with the results!

nice article by the way!

Jazzy G

Take a look at this: https://github.com/tttapa/Control-Surface/blob/master/examples/Ex.14.LED/Ex.14.LED.ino