The first thing we need to tackle before anything else is sending a proper midi sysex initialization. The reason we will require proper initialization via sysex is because the APC40 has a peculiar boot up. If it is turned on without ableton live running, it defaults to a standalone mode. This mode forces midi feedback when buttons are pressed. This is useful for quickly mapping things, but seriously limits the functionality. If we initialize the APC40 with the proper sysex, we can tell it to boot up into ableton live mode, this avoids any forced midi feedback, but it means we need to implement everything ourselves. This is exactly what we need.
The current definition is located in Editor > Gui > Interaction > Midi > CompatibleDevices > Apc40Mk2.cs
Lets review what we have in Apc40Mk2.cs:
Show Code
if (!_initialized)
{
// NOTE: This invocation doesn't seem to have an effect
Log.Debug("Sending init SysEx message to APC40...");
var buffer = new byte[]
{
0xF0, // MIDI excl start
0x47, // Manu ID
0x7F, // DevID
0x73, // Prod Model ID
0x60, // Msg Type ID (0x60=Init?)
0x00, // Num Data Bytes (most sign.)
0x04, // Num Data Bytes (least sign.)
0x42, // Device Mode (0x40=unset, 0x41=Ableton, 0x42=Ableton with full ctrl)
0x01, // PC Ver Major (?)
0x01, // PC Ver Minor (?)
0x01, // PC Bug Fix Lvl (?)
0xF7, // MIDI excl end
};
MidiOutConnection?.SendBuffer(buffer);
_initialized = true;
}Wait? What is this? NOTE: This invocation doesn’t seem to have an effect. Well, that’s no good. Let’s duplicate the whole file and rename it APC40mk1.cs for editing and review the changes we need to make.
Looking at: [MidiDeviceProduct(“APC40 mkII”)]
This is the identifier of the midi device, since we are using mk1 we need to change it to:
[MidiDeviceProduct(“Akai APC40”)]
Since this is a new class, we also need to update the class names:
public sealed class Apc40Mk2 to public sealed class Apc40Mk1
public Apc40Mk2() to public Apc40Mk1()
Now we save it and move on. Let’s implement a proper sysex initialization for the APC40mk1.
Show Code
if (!_initialized)
{
// Should be: F0 47 00 73 60 00 04 xx 08 01 01 F7
Log.Debug("Sending init SysEx message to APC40 Mk1...");
var buffer = new byte[]
{
0xF0, // MIDI exclusive start
0x47, // Manufacturers ID Byte
0x00, // System Exclusive Device ID
0x73, // Product model ID
0x60, // Message type identifier
0x00, // Number of data bytes to follow (most significant)
0x04, // Number of data bytes to follow (least significant)
0x40, // Application/Configuration Identifier (40 for Generic, 41 for Ableton Live Mode, 42 for Alternate Ableton Live Mode)
0x08, // PC application Software version major (Set to 8.1.1 but doesn't matter)
0x01, // PC application Software version minor (Set to 8.1.1 but doesn't matter)
0x01, // PC application Software bug-fix level (Set to 8.1.1 but doesn't matter)
0xF7 // MIDI exclusive end
};
MidiOutConnection?.SendBuffer(buffer);
_initialized = true;
}This is the proper sysex format for the APC40mk1. What we are most interested in now is:
0x40, // Application/Configuration Identifier (40 for Generic, 41 for Ableton Live Mode, 42 for Alternate Ableton Live Mode)
By toggling this byte to either 41 or 42, it will boot itself into the correct mode we need to map it properly.
While I was in here, I also updated the colors as they are only limited in the mk1 to:
- off
- green, blinking green
- orange, blinking orange
- red, blinking red
All testing is working great. Issued a PR to include into the Tixl project: https://github.com/tixl3d/tixl/pull/868
** NOTE: In order to ensure backward-compatibility with anyone using the Generic 0x40 mode, The configuration has this set by default. In order to use the Ableton mode correctly, you will have to edit Apc40Mk1.cs and change the byte flag from 0x40 to 0x41 or 0x42.
Future Ideas:
- While implementing the proper sysex, I found myself wanting to be able to send this byte buffer during runtime, instead of just when initializing the midi device. This will need a byte operator type to avoid the need to convert every byte from HEX into decimal (int) individually. The sysex init could be sent to clear the all controls back to off/0. Also can be used for midi program/bank changes in the future.
