Akai MPK261 (MPK2 series): Controlling the controller with SysEx

In this (very) technical post, I explain a method that will give you better control over the behavior of your Akai MPK2 series keyboard (tested on an MPK261). The goal is to be able to select one of the 30 “presets” stored in the keyboard on demand, without touching a button on the controller. A side benefit is that you can create an infinite number of presets and store them on your computer, and reload them in the MPK as needed.

  • Part 1: What needs to be sent to the MPK2 series?
  • Part 2: How to send a SysEx Message to the MPK2 Series?
  • Part 3: Going further
    • Part 3.1: Creating more Presets
    • Part 3.2: Managing SysEx libraries
  • Conclusion

Part 1: What needs to be sent to the MPK?

What we want to do is select the active preset at a given moment. Normally, you choose a preset using the rotary knob to the right of the display. I found a way to select a preset remotely. As you might know, the MPK2 series does not react when receiving a Midi Program Change command. I think that this should work, but it does not (tested). With some reverse engineering and a bit of luck, I found a simple way to select a preset directly.

To change the preset remotely, you will have to send a SysEx Message to the keyboard. Here is the format (in Hexadecimal):

F0 47 00 25 30 00 04 01 00 01 xx F7

“F0 47 00 25” is the SysEx header identifying the MPK261. “F0” is the standard SysEx beginning byte. “47 00” identifies AKAI as the manufacturer and 25 is the devices model number. This ensures that only the MPK will respond to that SysEx. Since I only have an MPK261, I cannot be certain that this exact sequence will work on other Series 2 controllers (let me know in the comments), but it should be very close in any case. Maybe just a matter of changing the 25 to something else. “30 00 04 01 00 01 xx” is the actual command. The MPK translates it to “load this Preset”. “xx” is the preset number, from 00 (preset 1) to 1D (preset 30). “F7” is the standard SysEx termination byte.

Pretty simple, isn’t it? It took me a while to figure it out (no thanks to Akai…).

Part 2: How to send a SysEx message to the MPK?

There are many ways to send SysEx from a computer, micro-controller or a Midi controller, so let me first give you a few examples (I work on a Mac, but equivalent methods exist for the PC or Linux):

I use Processing for testing (also available on Windows and Linux). In processing, I use themidibus library to handle Midi communications. If you are a programmer, you might have another way of sending hexadecimal to a Midi instrument. It’s definitely doable with C++, C#, java, Python and many more.

The command is straightforward: (this one will load preset 0x12, or 18 in decimal)

 myBus.sendMessage(
 new byte[] {
 (byte)0xF0, (byte)0x47, (byte)0x00, (byte)0x25,
 (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x01, (byte)0x00, (byte)0x01, (byte)0x12, (byte)0xF7
 }
 );

Click on the link to see the full Processing program that will send a SysEx command:

import themidibus.*; //Import the library
import javax.sound.midi.MidiMessage; //Import the MidiMessage classes http://java.sun.com/j2se/1.5.0/docs/api/javax/sound/midi/MidiMessage.html
import javax.sound.midi.SysexMessage;
import javax.sound.midi.ShortMessage;

MidiBus myBus; // The MidiBus

void setup() {
  size(400, 400);
  background(0);

  MidiBus.list(); // List all available Midi devices on STDOUT. This will show each device's index and name.
  myBus = new MidiBus(this, 3, 4); // Create a new MidiBus object

  // On mac you will need to use MMJ since Apple's MIDI subsystem doesn't properly support SysEx.
  // However MMJ doesn't support sending timestamps so you have to turn off timestamps.
  myBus.sendTimestamps(false);
  noLoop(); //execute the program only once
}

void draw() {

  //We will send a variable length sysex message
  //IMPORTANT: On mac you will have to use the MMJ MIDI subsystem
  //to be able to send SysexMessages. Consult README.md from themidibus documentation
  // for more information

  myBus.sendMessage(
  new byte[] {
    (byte)0xF0, (byte)0x47, (byte)0x00, (byte)0x25,
    (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x01, (byte)0x00, (byte)0x01, (byte)0x12, (byte)0xF7
  }
  );

  //We could also do the same thing this way ...

  try { //All the methods of SysexMessage, ShortMessage, etc, require try catch blocks
    SysexMessage message = new SysexMessage();
    message.setMessage(
    0xF0,
    new byte[] {
      (byte)0x47, (byte)0x00, (byte)0x25,
      (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x01, (byte)0x00, (byte)0x01, (byte)0x12, (byte)0xF7
    }
    ,
    11 //number of bytes in the SysEx command
    );
    myBus.sendMessage(message);
  }
  catch(Exception e) {
  }
  //End of "try" and "catch"
}

Instead of writing code, you might use a SysEx Librarian, a special program that will store and send SysEx messages to your equipment. On a Mac, I use the aptly named “SysEx librarian” software. On a PC, “MidiOX” should do the same.

What if you want to automate the process (i.e. send a SysEx message when some event happens on your keyboard or computer)?

If you look at the code above, it’s fairly simple to add a short piece of code that will receive a command, like a Midi Program Change (PC) and send the appropriate SysEx Message.

Here’s a Processing code example that will identify an incoming Program Change command (combined with the code above, it could send a SysEx right away):

  if (midiCommand[0] != 0) {
    println("Midi Command: " + (int)(midiCommand[0] & 0xF0));
    println("Channel:"+(int)(midiCommand[0] & 0x0F));
    for (int i = 1;i < midiCommand.length;i++) {
      println("Param "+(i+1)+": "+(int)(midiCommand[i] & 0xFF));
    }
    if ((int)(midiCommand[0] & 0xF0) == 192){
      println("Received Program Change");
    //send your SysEx here
    }
    midiCommand[0] = 0;
  }
}

Click on the link to see the full Processing program:

import themidibus.*; //Import the library
import javax.sound.midi.MidiMessage; //Import the MidiMessage classes http://java.sun.com/j2se/1.5.0/docs/api/javax/sound/midi/MidiMessage.html
import javax.sound.midi.SysexMessage;
import javax.sound.midi.ShortMessage;

MidiBus myBus; // The MidiBus

byte[] midiCommand = {
  0, 0, 0
};

void setup() {
  size(400, 400);
  background(0);

  MidiBus.list(); // List all available Midi devices on STDOUT. This will show each device's index and name.
  myBus = new MidiBus(this, 3, 4); // Create a new MidiBus object

  // On mac you will need to use MMJ since Apple's MIDI subsystem doesn't properly support SysEx.
  // However MMJ doesn't support sending timestamps so you have to turn off timestamps.
  myBus.sendTimestamps(false);
}

void draw() {

  if (midiCommand[0] != 0) {
    println("Midi Command: " + (int)(midiCommand[0] & 0xF0));
    println("Channel:"+(int)(midiCommand[0] & 0x0F));
    for (int i = 1;i < midiCommand.length;i++) {
      println("Param "+(i+1)+": "+(int)(midiCommand[i] & 0xFF));
    }
    if ((int)(midiCommand[0] & 0xF0) == 192){
      println("Received Program Change");
    //send your SysEx here
    }
    midiCommand[0] = 0;
  }
}

// Notice all bytes below are converted to integeres using the following system:
// int i = (int)(byte & 0xFF)
// This properly convertes an unsigned byte (MIDI uses unsigned bytes) to a signed int
// Because java only supports signed bytes, you will get incorrect values if you don't do so

void rawMidi(byte[] data) { // You can also use rawMidi(byte[] data, String bus_name)
  // Receive some raw data
  // data[0] will be the status byte
  // data[1] and data[2] will contain the parameter of the message (e.g. pitch and volume for noteOn noteOff)
  println();
  println("Raw Midi Data:");
  println("--------");
  println("Status Byte/MIDI Command:"+(int)(data[0] & 0xFF));
  midiCommand[0] = data[0];
  println("Command:"+(int)(data[0] & 0xF0));
  println("Channel:"+(int)(data[0] & 0x0F));
  // N.B. In some cases (noteOn, noteOff, controllerChange, etc) the first half of the status byte is the command and the second half if the channel
  // In these cases (data[0] & 0xF0) gives you the command and (data[0] & 0x0F) gives you the channel
  for (int i = 1;i < data.length;i++) {
    println("Param "+(i+1)+": "+(int)(data[i] & 0xFF));
    midiCommand[i] = data[i];
  }
}

Because I use Ableton, and it is quite retarded about passing midi messages along, I have to use a version of the code above to do the SysEx thing. Some DAW can do it natively. It’s also possible in Ableton when using Max for Live (but that will be another post).

Basically, the Processing program waits for a Program Change command (preferably on a determined channel), sent from Ableton (about the only Midi thing that Ableton can send) or from a pedal board (good’old Behringer FCB1010 in my tests) or even from the MPK keyboard itself!(the pads and DAW buttons can send Program Change) It then sends a SysEx message and the MPK loads the requested Preset from memory.

Other programs exist to automate the process, like Bome’s Midi Translator (take a look at their “sendSX” too), ThePez Ableton plugin or MidiPipe, available for free.

Another way to do the PCtoSysEx translation is to use an Arduino (or any other micro-controller solution, including MidiSolutions’ Event Processor ) that listens to Midi traffic and takes the appropriate action when necessary. The idea is the same and some of the code is similar. The advantage is that your main computer doesn’t have to run software that sits there eating CPU waiting for incoming Program Changes (Java, used by Processing, is quite CPU hungry). The Arduino can even be plugged right after the MPK to filter and replace the Midi commands in one go, before they reach other equipment or your computer. The disadvantage is additional equipment. I have tested this and it works well. I can make the Arduino code available if necessary.

That’s all pretty simple: Send a short SysEx message to the MPK2 series using one of the many methods available. So you now how to instantly load any of the 30 presets stored on the MPK. But what if you need more than 30 presets?

Part 3: Going Further

I love MPK presets. They store nearly every parameter of the MPK2 series, except a few global parameters like Keyboard Curves, Pad thresholds. Once I set a preset to my liking, I try not to modify it. So, like many others, I run out of presets.

On the MPK, you can modify any preset. You can also store these modified presets on your computer and reload then when necessary. That’s the key! Here’s the method:

  • Modify the preset on the MPK
  • Send the preset to your computer
  • Receive the preset with software or your DAW
  • Store the preset in your library
  • Reload the preset when needed

Let’s look at this in detail:

  • Modify the preset on the MPK

You should know how to do this by now. The key here is that as soon as you modify a parameter, its new value is stored in the loaded (active) preset. To save it in memory, or to actually modify the preset, you first have to be in “Preset” mode. Then you have to press the right arrow on the right side of the display and press enter (push the rotary encoder next to the display). If you reload that preset (using the encoder or one of the methods above), you changes are reloaded. Presets are kept in memory until you modify them again.

  • Send the preset to your computer

To send a preset, or all of them, to the computer, press “Global” and then the right arrow until you see “Send Program:”. It might say “Send Program: ALL” or instead show a number (from 1 to… 30). I prefer to send just one program. Now, before you press the encoder to actually send the “Program”, you have to do the next step:

  • Receive the preset with software or your DAW

I use “SysEx Librarian”. You can use any program that can receive SysEx and store it. Some DAWs offer that possibility. In my case, I just choose “MPK261 Port A” as the Midi port and then press the rotary encoder on the MPK. What the keyboard sends is a SysEx “file” of 1555 bytes for each preset (or Program). These bytes contain all the information needed for every single parameter for every knob, button, slider, pedal, pad and wheel on the selected preset.

  • Store the preset in your library

By now, you’ve figured that you can save that SysEx file somewhere in a directory on your computer. Take that opportunity to rename the file with a meaningful name (instead of “Preset 12″…). So if you repeat the first 3 steps for every single preset that you want to create/modify and save, you build your preset library.

  • Reload the preset when needed

When you need to reload a preset saved on your computer, you simply have to send that SysEx to the MPK2 series keyboard. If you use SysEx librarian, you just have to click on the chosen preset and press PLAY. The MPK will receive the SysEx and load it in place of the preset with the same number. Of course, there’s a catch there: what if you want to change the number in the preset, to, say, load it as preset number 8? Well, this is a bit more advanced, but all you have to do is find a Hex editor, like “Hex Friend” (Mac) and replace byte 0x07 (the 8th byte) in the file by the number of the preset you want to replace (in  hexadecimal, of course). By the way, bytes 0x08 to 0x0F contain the preset name, in plain text. You might want to modify that too. It’s a lot faster to modify the preset name in the file than it is using the rotary encoder on the MPK!

That last part is a bit more technical, but it lets you create and infinite number of presets, stored on your computer, with meaningful file names (with more than 8 characters).

Conclusion

The AKAI MPK261 is the best keyboard/controller I’ve ever used. With this method of recalling presets the fine tuning of parameters becomes much more flexible. If, like me, you are using Ableton Live, this really helps coupling the controller and the software.

The are some potential problems though. Recalling a stored preset takes about 1/2 second, because there is additional SysEx messages sent by the MPK and that ties it down for some milliseconds. Second, loading a preset from the computer requires a few seconds of attention from the MPK. So I just plan accordingly: I recall stored presets as needed because I plan for the brief interruption in the musical score, and I upload presets between tunes (I never imagined needing more than 30 presets in a single piece!).

This entry was posted in Music equipment and tagged , , . Bookmark the permalink.

6 Responses to Akai MPK261 (MPK2 series): Controlling the controller with SysEx

  1. Brian says:

    Many thanks for sharing this great info!

    One quick question about this comment on changing the preset location: “…replace byte 0x07 (the 8th byte) in the file by the number of the preset you want to replace (in hexadecimal, of course). “:

    Does this range go from 0 to 29, or 1 to 30?

  2. Roger Wilco says:

    Thanks so much for taking the time to write this up! I found it incredibly helpful.

  3. Denoiser says:

    Hi,

    do you maybe know whats the sysex msg which enables all buttons and switches to send sysex code when pressed; or any other sysex messages except preset load/store ?

    • Credo says:

      I don’t think the MPK2 firmware supports sending custom sysex messages itself. The only sysex the MPK2 can send is to dump individual presets, or to do a bulk dump of all it’s presets.

      You could use some sort of software (Bome, Bidule, etc.) ‘in the middle’ to transform some other MIDI event(s) into sysex.

      I.E. Install something like Bome, along with a loopMIDI port. Connect the MPK2 into Bome. Have Bome set to send output to a virtual loopMIDI port. Get Keyboard controller in your DAW from that virtual port.

      Inside Bome, you could set it so if gets a particular MIDI event…I.E. a program change, or a specific CC message…it would ‘transform’ that into whatever sysex you punch into Bome.

      Some DAWs might even have built in transformers and/or synth profilers that can do these sorts of things.

    • rt says:

      @Denoiser,
      Credo is right. The MPK2 will not send SysEx. His suggestions for software that can take care of this a good. There are also hardware devices, like Bome’s soon-to-be available device, and others available from midi solutions.com. I’m also developing my own Midi Processor. Details will be published on this blog soon.

Leave a Reply

Your email address will not be published. Required fields are marked *