This year I impulse-bought an AKAI MPK mini Pro 2-octave MIDI device.
And found that, apparently, if you want to do anything with Midi music, you buy a Mac.
Well, I’ve always found Mac/Apple UI to be unusable, so that’s out.
Anyway, it turned out to be easy to get MIDI messages from a USB device to a Python program using python-mido
. And, after some dithering, creating sound from Midi was do-able. I tweaked one of several variants of fluidsynth.py
on GitHub. The actual instruments came from various SoundFont files downloaded from the magical Internet. My favorite of the 48 I have is gigabyte-sized Compifont_13082016.sf2
.
Re-inventing the wheel can be entertaining.
In the course of playing with the AKAI I made the following notes about the AKAI’s sysex and light control logic. Make of them what you will.
""" Some things found about the Akai Pro Mini using (after plugging the device alone in to USB bus 3 - the near plug on the front panel of spring): sudo modprobe usbmon # makes the /dev/usb/usbmon[0-7] devices sudo cat /sys/kernel/debug/usb/usbmon/3u # doesn't print more than 24 real data bytes at a time (32 bytes packaged in 8 4-byte words) Note: Each 4 bytes has a 04 as the 1st byte and a 07 instead of 04 on the last 3 real data bytes. Or: sudo tcpdump -i usbmon3 -x Note: https://github.com/mungewell/mpd-utils/blob/master/sysex/sysex_mk2.md has some sysex reverse-eng info for the device Note: private/akai/APC40Mk2_Communications_Protocol_v1.2.pdf for a similar device (some note on the web said this MPKmini doesn't have such a doc) MPK Mini sysex from device sysex data=( 71, Akai device 71==0x47 0, More Akai dev? (which particular device? - 0x7f is broadcast, apparently, and 0x7e is non-real-time?) 38, Akai model 38==0x26 103, sysex function 103|0x67 is (prog_memory below: 0..4=RAM|prog1..4) coming from device. 102|0x66 requests a program (prog_memory below: 0..4=RAM|prog1..4) from device. 100|0x64 puts program to device. 96|0x60 requests the knob positions (see the code for example). 97|0x61 is knob positions from the device. 0, hi-7-bits of how many bytes 109, how many more bytes there are or are meant to be if the device didn't have bugs? 0, prog memory 0=RAM 1=prog1 2..4=prog2..4 0, pad channel 0..15 0, key channel 0..15 4, key octave 0..8 4 + octave (changes LEDs) 0, arp off=0 on=1 (changes LED) 0, arp mode 0..5 0, arp time div 0..7 0, arp clock internal=0 external=1 0, arp latch on=1 off=0 0, arp swing 0..5 50%|55%|57%|59%|61%|64% 3, arp tempo taps 2..4 1, hi bit arp tempo 30..240 0, lo 7 bits arp tempo 30..240 0, arp octave 0..3 (displayed on-screen in Akai setup program and on device's keys in red as 1..4) 0, 0=pitchbend 1=cc1 2=cc2 0, cc1|cc2-down 0..127 0, cc2-up 0..127 2, cc2 65, cc2-down 65 64, cc2-up 64 48, note_on note when not in CC or PC mode 0, cc 0, pc 1, momentary=0 toggle=1 49,1,1,1, 50,2,2,1, 51,3,3,1, 52,4,4,1, 53,5,5,1, 54,6,6,1, 55,7,7,1, 56,8,8,1, 57,9,9,1, 58,10,10,1, 59,11,11,1, 60,12,12,1, 61,13,13,1, 62,14,14,1, 63,15,15,1, 0, cc 0, lo 127, hi 1,0,127, 2,0,127, 3,0,127, 4,0,127, 5,0,127, 6,0,127, 7,0,127, 12 0..24 12 + transpose of -12..12 ) """ # # # If the device is in the right state, apparently any channel 0 note_on (non-127?) will turn off the PROG_CHANGE light until some other note_on messages are sent or something. # led_lite values: # 0..2 At start-up most recent is Prog Change - it turns off/on. # 3 Apr On/Off # 4 Tap_tempo changes only if human has turned off Arp # 5 Octave down # 6 Octave up # 7 Full level # 8 ? # 9..16 Pads # 17..24 Most recently used lite. # 25 Bank A/B if Green, off goes to off or red, whichever it was last set by the human. Human-set red cannot be turned off. # 26 CC # 27 Prog Change # Other led_lite values are just weird. Most recent lite changed or something is affected. # The lites don't affect the meaning of the button. The button must be hand-toggled from its logical state to get to a state that matches the lite after the lite is turned off. # # The 127-ness came from a comment at: https://cycling74.com/forums/akai-mpk-mini-send-get-signals-to-light-buttons # # AKAI_MPK_MINI_LITES = [ [ 3, "Arp", ], [ 4, "Tap_Tempo", ], [ 5, "Oct_down", ], [ 6, "Oct_up", ], [ 7, "Full_level", ], [ 9, "Pad_1", ], [ 10, "Pad_2", ], [ 11, "Pad_3" ], [ 12, "Pad_4", ], [ 13, "Pad_5", ], [ 14, "Pad_6", ], [ 15, "Pad_7", ], [ 16, "Pad_8", ], [ 25, "Bank_A/B", ], [ 26, "CC", ], [ 27, "Prog_change", ], ]