Skip to content

MPC internal controller Midi aspects

TheKikGen edited this page Nov 25, 2023 · 29 revisions

MPC Live Controller Midi messages

This analysis concerns mainly the MPC Live, and is probably applicable to the overall last generation MPC family, including the Force.
It was done with a special library I wrote , that being used with LD_PRELOAD allows to dump all midi traffic between the MPC standalone software and the MPC controller on the console.

You will find more details here : https://github.com/TheKikGen/MPCLiveXplore-libs#tkgl_ctrldump

MPC CC internal controller mapping

The MPC Live controller is connected internally to the USB bus. So it is possible to see it with a classical "amidi -l linux command" :

# amidi -l
Dir Device    Name
IO  hw:1,0,0  MPC Public
IO  hw:1,0,1  MPC Private
IO  hw:1,0,2  MPC MIDI Port A
IO  hw:1,0,3  MPC MIDI Port B
# 

The MPC Live has 2 "external" jack midi ports, that are connected to the USB port A / B by the MPC software.
The PUBLIC port on cable 0 is used to handle specific sysex traffic, and notably pads leds and colors.
The PRIVATE port on cable 1 is used to manage buttons, buttons led, and pad press.

when launched, the first sysex message sent by the MPC software (MPC) is a universal identity request sysex message ( check midi.org universal sysex messages ) :

MPC      --> hw:1,0,0 = F0 7E 00 06 01 F7                                | .~....

The controller will reply by saying "hi I'm a MPC Live", and will send the serial number (replaced by X in the dump below) :

                                           v---- 3B here is the identification code of the MPC LIVE
hw:1,0,1 --> MPC      = F0 7E 00 06 02 47 3B 00 19 00 01 01 01 7F 00 00  | .~...G;.........
                        00 00 41 31 XX XX XX XX XX XX XX XX XX XX XX XX  | ..A1XXXXXXXXXXXX
                        XX 00 F7                                         | X..

The reply can be parsed as follow :
Identity reply : F0 7E 00 06 02
ManufacturerID : 47 (Akai)
ProductID : 3B (MPC Live)
DeviceID : 7F (none)
FWVersion : 01.11
Reserved : 00000000
Serial# data : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Then, the software sends some color pads initialization to set all pads to "black" :

F0 47 7F 3B 64 00 03 00 01 01 F7 
F0 47 7F 3B 64 00 03 01 01 01 F7 
F0 47 7F 3B 64 00 03 02 00 00 F7 
etc....    

The "pad color" sysex message has the following structure :
F0 47 7F 3B 65 00 04 [Pad #] [R] [G] [B] F7

The full message :

MPC      --> hw:1,0,0 = F0 47 7F 3B 62 00 01 65 F7 F0 47 7F 3B 64 00 03  | .G.;b..e..G.;d..
                        00 01 01 F7 F0 47 7F 3B 64 00 03 01 01 01 F7 F0  | .....G.;d.......
                        47 7F 3B 64 00 03 02 00 00 F7 F0 47 7F 3B 64 00  | G.;d.......G.;d.
                        03 03 00 00 F7 F0 47 7F 3B 63 00 03 00 00 00 F7  | ......G.;c......
                        F0 47 7F 3B 63 00 03 01 00 00 F7 F0 47 7F 3B 41  | .G.;c.......G.;A
                        00 00 F7 F0 7E 00 06 01 F7                       | ....~....

Then MPC asks again an identity request, and sends some more pad settings, with default colors :

hw:1,0,1 --> MPC      = F0 47 7F 3B 64 00 03 00 01 01 F7 F0 47 7F 3B 64  | .G.;d.......G.;d
                        00 03 01 01 01 F7 F0 47 7F 3B 64 00 03 02 00 00  | .......G.;d.....
                        F7 F0 47 7F 3B 64 00 03 03 00 0A F7              | ..G.;d......

hw:1,0,1 --> MPC      = F0 47 7F 3B 41 00 13 00 00 00 00 00 00 00 00 00  | .G.;A...........
                        00 00 00 00 00 00 00 00 00 00 F7                 | ...........

hw:1,0,1 --> MPC      = F0 7E 00 06 02 47 3B 00 19 00 01 01 01 7F 00 00  | .~...G;.........
                        00 00 41 31 XX XX XX XX XX XX XX XX XX XX XX XX  | ..A1XXXXXXXXXXXX
                        XX 00 F7                                         | X..

MPC      --> hw:1,0,0 = F0 47 7F 3B 65 00 04 00 00 00 00 F7 F0 47 7F 3B  | .G.;e........G.;
                        65 00 04 01 00 00 00 F7 F0 47 7F 3B 65 00 04 02  | e........G.;e...
                        00 00 00 F7 F0 47 7F 3B 65 00 04 03 00 00 00 F7  | .....G.;e.......
                        F0 47 7F 3B 65 00 04 04 00 00 00 F7 F0 47 7F 3B  | .G.;e........G.;
                        65 00 04 05 00 00 00 F7 F0 47 7F 3B 65 00 04 06  | e........G.;e...
                        00 00 00 F7 F0 47 7F 3B 65 00 04 07 00 00 00 F7  | .....G.;e.......
                        F0 47 7F 3B 65 00 04 08 00 00 00 F7 F0 47 7F 3B  | .G.;e........G.;
                        65 00 04 09 00 00 00 F7 F0 47 7F 3B 65 00 04 0A  | e........G.;e...
                        00 00 00 F7 F0 47 7F 3B 65 00 04 0B 00 00 00 F7  | .....G.;e.......
                        F0 47 7F 3B 65 00 04 0C 00 00 00 F7 F0 47 7F 3B  | .G.;e........G.;
                        65 00 04 0D 00 00 00 F7 F0 47 7F 3B 65 00 04 0E  | e........G.;e...
                        00 00 00 F7 F0 47 7F 3B 65 00 04 0F 00 00 00 F7  | .....G.;e.......
                        F0 47 7F 3B 5A 00 20 00 00 03 04 00 00 05 05 00  | .G.;Z. .........
                        00 00 01 02 0A 03 0F 00 00 00 01 00 00 00 00 00  | ................
                        00 00 01 00 00 00 00 F7                          | ........

MPC      --> hw:1,0,1 = B0 02 02 B0 03 02 B0 05 02 B0 06 02 B0 08 02 B0  | ................
                        73 02 B0 74 02 B0 23 03 B0 24 01 B0 25 01 B0 26  | s..t..#..$..%..&
                        01 B0 27 02 B0 28 01 B0 2A 02 B0 2B 02 B0 2C 01  | ..'..(..*..+..,.
                        B0 2D 01 B0 2E 03 B0 2F 01 B0 30 01 B0 49 01 B0  | .-...../..0..I..
                        50 01 B0 51 03 B0 52 01 B0 53 01 B0 34 02 B0 43  | P..Q..R..S..4..C
                        02 B0 7A 01 B0 31 01 B0 35 03 B0 36 01 B0 37 01  | ..z..1..5..6..7.
                        B0 33 01 B0 70 02 B0 71 03 B0 00 01 B0 0B 01 B0  | .3..p..q........
                        09 01 B1 10 02 B0 10 59 B1 11 01 B0 11 00 B1 12  | .......Y........
                        01 B0 12 00 B1 13 02 B0 13 59 B1 14 01 B0 14 00  | .........Y......
                        B1 15 01 B0 15 00 B1 16 02 B0 16 00 B1 17 02 B0  | ................
                        17 00 B1 18 01 B0 18 00 B1 19 02 B0 19 00 B1 1A  | ................
                        02 B0 1A 3F B1 1B 03 B0 1B 3F B1 1C 01 B0 1C 0D  | ...?.....?......
                        B1 1D 02 B0 1D 00 B1 1E 01 B0 1E 00 B1 1F 01 B0  | ................
                        1F 7F B0 75 01 B0 76 01 B0 7B 02 B0 32 02 B0 29  | ...u..v..{..2..)
                        02 B0 7D 02 B0 7E 02 B0 7F 02 B0 3B 02 B0 3C 02  | ..}..~.....;..<.
                        B0 3D 02 B0 3E 02 B0 3F 03 B0 4A 02 B0 4B 04 B0  | .=..>..?..J..K..
                        4C 02 B0 4D 02                                   | L..M.

MPC      --> hw:1,0,0 = F0 47 00 3B 50 00 10 05 04 0A 0A 07 0B 00 08 01  | .G.;P...........
                        0C 0C 0C 00 03 0F 0E F7                          | ........

MPC      --> hw:1,0,1 = B0 14 7F B0 15 3F B0 17 7F                       | .....?...

hw:1,0,1 --> MPC      = F0 47 7F 3B 51 00 20 03 0C 02 0B 05 0D 04 0E 02  | .G.;Q. .........
                        03 0D 05 0B 09 06 0C 05 04 0A 0A 07 0B 00 08 01  | ................
                        0C 0C 0C 00 03 0F 0E F7                          | ........

At this point, the "tap" starts to blink. This is done by sending a led full light/dim Control Change midi message to the tap button :

MPC      --> hw:1,0,1 = B0 35 01                                         | .5.

MPC      --> hw:1,0,1 = B0 35 03                                         | .5.

MPC      --> hw:1,0,1 = B0 35 01                                         | .5.

And that's globally all you have to know.
All buttons are mapped as note on/off when pressed/released.
Check the figure at the top of that note.

You can send midi message on the command line with the amidi command. ex :

This lights the REC, OVERDUB, STOP and PLAY buttons:

$ amidi -p hw:1,0,0 -S 'b0 49 01 b0 50 01 b0 51 03 b0 52 01'

Light some pads :

amidi -p hw:1,0,0 -S 'b0 49 01 b0 50 01 b0 51 03 b0 52 01'

MPC Sysex messages

Somes sysex messages were partially decoded (thanks to Lenore Byron from the MPC Hacking group).

Sysex Format:

	F0 47 00 pid cmd plh pll [payload] F7

	[ F0 47 00 ] - Akai Prefix
	[ pid ] - Product ID:
		3A - MPC X controller
		3B - MPC Live
		46 - MPC One
		47 - MPC Live II
		40 - MPC Force
		41 - MPC Force 6 (Unreleased)

	[ plh plh ] - Payload Length

Known Sysex Commands:

	0B - Set OLED Pixels (Payload 7 or more bytes)
		- 5 command bytes, followed by payload bytes
		- Payload bytes are packed into 7 bit bytes, MSB-first
		- Command:
			[display] [starty] [endy] [startx] [endx]
			Displays are 128x32 pixels

	0C - Unknown (Payload 7, 9, 11, ... bytes)
	10 - Unknown (Payload 7 bytes)
	40 - Unknown (No Payload)
		Reply: F0 47 00 3A 40 0 13 [ 19 bytes ] F7

	41 - Unknown (No Payload)
		Reply: F0 47 00 3A 41 0 13 [ 19 bytes ] F7

	50 - Unknown (Payload 16 bytes)
		Reply: F0 47 00 3A 51 00 20 [ 32 bytes ] F7
	52 - Unknown (Payload 4 bytes)
		Reply: F0 47 00 3A 53 00 05 [ payload ] 02 F7
	54 - Unknown (Payload 2, 4, or 6 bytes)
	5A - Unknown (Payload 0 or 32 bytes) 
		- Pad configuration of some sort.

	62 - Unknown (Payload 1 byte)
		- Set midi port to send events to?

	64 - Unknown (Payload 3 bytes)
	65 - Set Pad color (Payload 4 bytes) : [Pad #] [R] [G] [B] F7
	72 - Enter DFU Mode
	78 - Unknown (Payload 4 bytes)
	79 - Unknown (Payload 16 bytes)
	

On the hardware side

The MPC controller is operated by a STM32F401, an ARM Cortex M4 based MCU, running probably at 84 MHz. The STM32F401 has usually from 128 to 512 Kbytes of Flash,96 Kbytes of SRAM, and :

  • 3x USARTs running at up to 10.5 Mbit/s,
  • 4x SPI running at up to 42 Mbit/s,
  • 3x I²C,
  • 1x SDIO,
  • 1x USB 2.0 OTG full speed,
  • 2x full duplex I²S up to up to 32-bit/192KHz,
  • 12-bit ADC reaching 2.4 MSPS,
  • 10 timers, 16- and 32-bit, running at up to 84 MHz

Firmware images for several MPCs can be found at usr/share/Akai/SME0/Firmware/.
A Firmware image is always named "update.dfu",has the DFuse file format, and are flashed in DFU mode. The .syx and .mid files are used to switch the MPC/Force in DFU update mode.

0000:0000 | 44 66 75 53  65 01 35 41  03 00 01 54  61 72 67 65 | DfuSe.5A...Targe
0000:0010 | 74 00 01 00  00 00 49 6E  74 65 72 6E  61 6C 20 46 | t.....Internal F
0000:0020 | 6C 61 73 68  00 00 00 00  00 00 00 00  00 00 00    | lash........... 

So, theoritecally, it is possible to modify that firmware and upload it in the controller.

0000:D260 | A0 70 47 2B  A0 70 47 2C  A0 70 47 00  00 00 0B 00 |  pG+ pG, pG.....
0000:D270 | 20 4D 50 43  20 50 75 62  6C 69 63 00  00 4D 50 43 |  MPC Public..MPC
0000:D280 | 20 50 72 69  76 61 74 65  00 4D 50 43  20 4D 49 44 |  Private.MPC MID
0000:D290 | 49 20 50 6F  72 74 20 41  00 4D 50 43  20 4D 49 44 | I Port A.MPC MID
0000:D2A0 | 49 20 50 6F  72 74 20 42  00 4D 50 43  20 4D 49 44 | I Port B.MPC MID
0000:D2B0 | 49 20 50 6F  72 74 20 43  00 4D 50 43  20 4D 49 44 | I Port C.MPC MID
0000:D2C0 | 49 20 50 6F  72 74 20 44  00 4A 61 63  6B 20 37 00 | I Port D.Jack 7.
0000:D2D0 | 00 4A 61 63  6B 20 38 00  00 4A 61 63  6B 20 39 00 | .Jack 8..Jack 9.
0000:D2E0 | 00 4A 61 63  6B 20 31 30  00 4A 61 63  6B 20 31 31 | .Jack 10.Jack 11
0000:D2F0 | 00 4A 61 63  6B 20 31 32  00 4A 61 63  6B 20 31 33 | .Jack 12.Jack 13
0000:D300 | 00 4A 61 63  6B 20 31 34  00 4A 61 63  6B 20 31 35 | .Jack 14.Jack 15
0000:D310 | 00 4A 61 63  6B 20 31 36  00 00 00 00  00 70 B5 18 | .Jack 16.....pµ.
0000:D320 | 49 05 46 4F  F4 80 63 01  22 A1 F1 1C  00 02 F0 8D | I.FOô.c."¡ñ...ð.
0000:D330 | FB 14 49 4F  F4 80 63 01  22 A1 F1 1C  00 02 F0 85 | û.IOô.c."¡ñ...ð.
0000:D340 | FB 11 4C 40  23 02 22 94  F8 26 10 28  46 FF F7 24 | û.L@#.".ø&.(Fÿ÷$
0000:D350 | FE 94 F8 27  10 40 23 02  22 28 46 FF  F7 1D FE 94 | þ.ø'.@#."(Fÿ÷.þ.

MPC Live controller switched to DFU mode ( F0 47 00 3B 72 00 00 F7) :

# PLATFORM_LOWER=$(cat /sys/firmware/devicetree/base/compatible | cut -f2 -d ',' | grep "acv\|ada")
# echo $PLATFORM_LOWER
acv8
# PLATFORM_UPPER=$(echo ${PLATFORM_LOWER}| tr '[:lower:]' '[:upper:]')
# echo $PLATFORM_UPPER
ACV8
# systemctl stop inmusic-mpc
# amidi --port "hw:1,0,1" --send /usr/share/Akai/SME0/Firmware/${PLATFORM_UPPER}/SysEx/DfuUpdate${PLATFORM_UPPER}.syx || abort "Could not enter
in dfu update mode"
# dfu-util -l
dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Found Runtime: [09e8:203b] ver=0111, devnum=4, cfg=1, intf=3, path="2-1.5", alt=0, name="MPC Live Audio DFU", serial="UNKNOWN"
Found Runtime: [09e8:203b] ver=0111, devnum=4, cfg=1, intf=3, path="2-1.5", alt=0, name="MPC Live Audio DFU", serial="UNKNOWN"
Found DFU: [0483:df11] ver=2200, devnum=10, cfg=1, intf=0, path="2-1.6", alt=3, name="@Device Feature/0xFFFF0000/01*004 e", serial="35xxxxxxxxxx"
Found DFU: [0483:df11] ver=2200, devnum=10, cfg=1, intf=0, path="2-1.6", alt=2, name="@OTP Memory /0x1FFF7800/01*512 e,01*016 e", serial="35xxxxxxxxxx"
Found DFU: [0483:df11] ver=2200, devnum=10, cfg=1, intf=0, path="2-1.6", alt=1, name="@Option Bytes  /0x1FFFC000/01*016 e", serial="35xxxxxxxxxx"
Found DFU: [0483:df11] ver=2200, devnum=10, cfg=1, intf=0, path="2-1.6", alt=0, name="@Internal Flash  /0x08000000/04*016Kg,01*064Kg,01*128Kg", serial="35xxxxxxxxxx"
# 

The "black pill" mini board has the same uC (STM32F401) than the MPC Live controller. I successfully updated that board with the MPC Live firmware :

Black Pill

# dfu-util -l
dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Found DFU: [0483:df11] ver=2200, devnum=8, cfg=1, intf=0, path="2-1.1", alt=3, name="@Device Feature/0xFFFF0000/01*004 e", serial="3988389A3034"
Found DFU: [0483:df11] ver=2200, devnum=8, cfg=1, intf=0, path="2-1.1", alt=2, name="@OTP Memory /0x1FFF7800/01*512 e,01*016 e", serial="3988389A3034"
Found DFU: [0483:df11] ver=2200, devnum=8, cfg=1, intf=0, path="2-1.1", alt=1, name="@Option Bytes  /0x1FFFC000/01*016 e", serial="3988389A3034"
Found DFU: [0483:df11] ver=2200, devnum=8, cfg=1, intf=0, path="2-1.1", alt=0, name="@Internal Flash  /0x08000000/04*016Kg,01*064Kg,01*128Kg", serial="3988389A3034"
Found Runtime: [09e8:203b] ver=0111, devnum=4, cfg=1, intf=3, path="2-1.5", alt=0, name="MPC Live Audio DFU", serial="UNKNOWN"
Found Runtime: [09e8:203b] ver=0111, devnum=4, cfg=1, intf=3, path="2-1.5", alt=0, name="MPC Live Audio DFU", serial="UNKNOWN"
# PLATFORM_LOWER=$(cat /sys/firmware/devicetree/base/compatible | cut -f2 -d ',' | grep "acv\|ada")
# PLATFORM_UPPER=$(echo ${PLATFORM_LOWER}| tr '[:lower:]' '[:upper:]')
# echo $PLATFORM_UPPER
ACV8
# dfu-util -a 0 -D /usr/share/Akai/SME0/Firmware/${PLATFORM_UPPER}/update.dfu || abort "Could not perform dfu update"
dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Match vendor ID from file: 0483
Match product ID from file: df11
Opening DFU capable USB device...
ID 0483:df11
Run-time device DFU version 011a
Claiming USB DFU Interface...
Setting Alternate Setting #0 ...
Determining device status: state = dfuERROR, status = 10
dfuERROR, clearing status
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 011a
Device returned transfer size 2048
DfuSe interface name: "Internal Flash  "
file contains 1 DFU images
parsing DFU image 1
Target name: Internal Flash
image for alternate setting 0, (1 elements, total size = 98312)
parsing element 1, address = 0x08008000, size = 98304
Download        [=========================] 100%        98304 bytes
Download done.
done parsing DfuSe file

Devices names from firmwares

ACV5 (MPC X)

Device : MPC X Controller 
Port   : MPC Public 
Port   : MPC Private 
Port   : MPC MIDI Port A 
Port   : MPC MIDI Port B
Port   : MPC MIDI Port C
Port   : MPC MIDI Port D

ACV8 (MPC Live)

Device : MPC Live Controller
Port   : MPC Public
Port   : MPC Private
Port   : MPC MIDI Port A
Port   : MPC MIDI Port B
Port   : MPC MIDI Port C
Port   : MPC MIDI Port D

ACVA (MPC One)

Device : MPC One MIDI
Port   : MPC Studio Live Public
Port   : MPC Studio Live Private
Port   : MPC Studio Live MIDI Port

ACVB (MPC Live 2)

Device : MPC Live II
Port   : MPC Public
Port   : MPC Private
Port   : MPC MIDI Port A
Port   : MPC MIDI Port B
Port   : MPC MIDI Port C
Port   : MPC MIDI Port D

ACVK (Force 6)

Device : Force 6 USB Device
Port   : Force 6 Public
Port   : Force 6 Private
Port   : Force 6 MIDI Port

ACVM (MPC Key 61)

Device : MPC Key 61
Port   : MPC Public
Port   : MPC Private
Port   : MPC MIDI Port A
Port   : MPC MIDI Port B
Port   : MPC MIDI Port C
Port   : MPC MIDI Port D

ADA2 (Force)

Device : Akai Pro Force  
Port   : Akai Pro Force Public
Port   : Akai Pro Force Private
Port   : Akai Pro Force MIDI Port