I bought an Akai MAX49 MIDI controller recently. It’s an impressive device boasting a nice, stiff keybed, a reasonably-supple set of pads and, of course, its big killer feature: Four banks of eight responsive LED touch faders designed primarily to make your neighbours jealous. A musician, upon unboxing such an instrument, might set about playing music with it; I, however, am no musician.
The first thing I did with my MAX49 was dive into its configuration settings in an effort to set it up just so for use with Propellerhead’s excellent Reason software. Akai offers some presets that work with Reason’s ‘Remote API’, an interesting and mysterious Lua-based scripting system for binding the various physical knobs and dials on any MIDI device to the virtual ones inside Reason. These are pretty good for the most part, but I encountered one major annoyance almost immediately: The controller’s ‘responsive’ faders (which one would expect to work just like the motorized ones on a mixing board) were capable of sending data out to Reason but not of receiving it from Reason. Thus I could use my finger and the MAX49 to move a fader on one of Reason’s virtual line mixers, but if I then used my mouse pointer to tweak that fader in the application the change would not be represented on my physical controller. This was not acceptable.
I did a bit of digging into the Remote API and the scripts Akai had provided. It turns out the reason for this is not that the device is incapable of being responsive, but that whoever wrote the script managed to include all this input-related stuff:
local inputs={ {pattern="b0 0C xx", name="Fader 1"}, {pattern="b0 0D xx", name="Fader 2"}, {pattern="b0 0E xx", name="Fader 3"}, {pattern="b0 0F xx", name="Fader 4"}, {pattern="b0 10 xx", name="Fader 5"}, {pattern="b0 11 xx", name="Fader 6"}, {pattern="b0 12 xx", name="Fader 7"}, {pattern="b0 13 xx", name="Fader 8"}, {pattern="b1 0C xx", name="Fader 9"}, {pattern="b1 0D xx", name="Fader 10"}, {pattern="b1 0E xx", name="Fader 11"}, {pattern="b1 0F xx", name="Fader 12"}, {pattern="b1 10 xx", name="Fader 13"}, {pattern="b1 11 xx", name="Fader 14"}, {pattern="b1 12 xx", name="Fader 15"}, {pattern="b1 13 xx", name="Fader 16"}, {pattern="b2 0C xx", name="Fader 17"}, {pattern="b2 0D xx", name="Fader 18"}, {pattern="b2 0E xx", name="Fader 19"}, {pattern="b2 0F xx", name="Fader 20"}, {pattern="b2 10 xx", name="Fader 21"}, {pattern="b2 11 xx", name="Fader 22"}, {pattern="b2 12 xx", name="Fader 23"}, {pattern="b2 13 xx", name="Fader 24"}, {pattern="b3 0C xx", name="Fader 25"}, {pattern="b3 0D xx", name="Fader 26"}, {pattern="b3 0E xx", name="Fader 27"}, {pattern="b3 0F xx", name="Fader 28"}, {pattern="b3 10 xx", name="Fader 29"}, {pattern="b3 11 xx", name="Fader 30"}, {pattern="b3 12 xx", name="Fader 31"}, {pattern="b3 13 xx", name="Fader 32"}, {pattern="b0 15 xx", name="Switch 1"}, {pattern="b0 16 xx", name="Switch 2"}, {pattern="b0 17 xx", name="Switch 3"}, {pattern="b0 18 xx", name="Switch 4"}, {pattern="b0 19 xx", name="Switch 5"}, {pattern="b0 1a xx", name="Switch 6"}, {pattern="b0 1b xx", name="Switch 7"}, {pattern="b0 1c xx", name="Switch 8"}, {pattern="b1 15 xx", name="Switch 9"}, {pattern="b1 16 xx", name="Switch 10"}, {pattern="b1 17 xx", name="Switch 11"}, {pattern="b1 18 xx", name="Switch 12"}, {pattern="b1 19 xx", name="Switch 13"}, {pattern="b1 1a xx", name="Switch 14"}, {pattern="b1 1b xx", name="Switch 15"}, {pattern="b1 1c xx", name="Switch 16"}, {pattern="b2 15 xx", name="Switch 17"}, {pattern="b2 16 xx", name="Switch 18"}, {pattern="b2 17 xx", name="Switch 19"}, {pattern="b2 18 xx", name="Switch 20"}, {pattern="b2 19 xx", name="Switch 21"}, {pattern="b2 1a xx", name="Switch 22"}, {pattern="b2 1b xx", name="Switch 23"}, {pattern="b2 1c xx", name="Switch 24"}, {pattern="b3 20 xx", name="Switch 25"}, {pattern="b3 21 xx", name="Switch 26"}, {pattern="b3 22 xx", name="Switch 27"}, {pattern="b3 23 xx", name="Switch 28"}, {pattern="b3 24 xx", name="Switch 29"}, {pattern="b3 25 xx", name="Switch 30"}, {pattern="b3 26 xx", name="Switch 31"}, {pattern="b3 27 xx", name="Switch 32"}, {pattern="9F 00", name="Pad D1", value="1"}, {pattern="9F 01", name="Pad D2", value="1"}, {pattern="9F 02", name="Pad D3", value="1"}, {pattern="9F 03", name="Pad D4", value="1"}, {pattern="9F 04", name="Pad D5", value="1"}, {pattern="9F 05", name="Pad D6", value="1"}, {pattern="9F 06", name="Pad D7", value="1"}, {pattern="9F 07", name="Pad D8", value="1"}, {pattern="9F 08", name="Pad D9", value="1"}, {pattern="9F 09", name="Pad D10", value="1"}, {pattern="9F 0A", name="Pad D11", value="1"}, {pattern="9F 0B", name="Pad D12", value="1"}, {pattern="e? xx yy", name="Pitch Bend", value="y*128 + x"}, {pattern="b0 01 xx", name="Mod Wheel"}, {pattern="b0 0b xx", name="Expression"}, {pattern="b0 40 xx", name="Damper Pedal"}, {pattern="d0 xx", name="Channel Pressure"}, {pattern="80 xx yy", name="Keyboard", value="0", note="x", velocity="64"}, {pattern="90 xx 00", name="Keyboard", value="0", note="x", velocity="64"}, {pattern="0 yy zz", name="Keyboard"}, {pattern="b0 73 7f", name="Rewind", value="1"}, {pattern="b0 74 7f", name="Fast Forward", value="1"}, {pattern="b0 75 7f", name="Stop", value="1"}, {pattern="b0 76 7f", name="Play", value="1"}, {pattern="b0 77 7f", name="Record", value="1"}, } remote.define_auto_inputs(inputs)
But NOT any corresponding output stuff, which I discovered looks very similar save for calling a different method in Reason’s API:
local outputs={ {pattern="b0 0C xx", name="Fader 1"}, {pattern="b0 0D xx", name="Fader 2"}, {pattern="b0 0E xx", name="Fader 3"}, {pattern="b0 0F xx", name="Fader 4"}, {pattern="b0 10 xx", name="Fader 5"}, {pattern="b0 11 xx", name="Fader 6"}, {pattern="b0 12 xx", name="Fader 7"}, {pattern="b0 13 xx", name="Fader 8"}, {pattern="b1 0C xx", name="Fader 9"}, {pattern="b1 0D xx", name="Fader 10"}, {pattern="b1 0E xx", name="Fader 11"}, {pattern="b1 0F xx", name="Fader 12"}, {pattern="b1 10 xx", name="Fader 13"}, {pattern="b1 11 xx", name="Fader 14"}, {pattern="b1 12 xx", name="Fader 15"}, {pattern="b1 13 xx", name="Fader 16"}, {pattern="b2 0C xx", name="Fader 17"}, {pattern="b2 0D xx", name="Fader 18"}, {pattern="b2 0E xx", name="Fader 19"}, {pattern="b2 0F xx", name="Fader 20"}, {pattern="b2 10 xx", name="Fader 21"}, {pattern="b2 11 xx", name="Fader 22"}, {pattern="b2 12 xx", name="Fader 23"}, {pattern="b2 13 xx", name="Fader 24"}, {pattern="b3 0C xx", name="Fader 25"}, {pattern="b3 0D xx", name="Fader 26"}, {pattern="b3 0E xx", name="Fader 27"}, {pattern="b3 0F xx", name="Fader 28"}, {pattern="b3 10 xx", name="Fader 29"}, {pattern="b3 11 xx", name="Fader 30"}, {pattern="b3 12 xx", name="Fader 31"}, {pattern="b3 13 xx", name="Fader 32"}, {pattern="b0 15 xx", name="Switch 1"}, {pattern="b0 16 xx", name="Switch 2"}, {pattern="b0 17 xx", name="Switch 3"}, {pattern="b0 18 xx", name="Switch 4"}, {pattern="b0 19 xx", name="Switch 5"}, {pattern="b0 1a xx", name="Switch 6"}, {pattern="b0 1b xx", name="Switch 7"}, {pattern="b0 1c xx", name="Switch 8"}, {pattern="b1 15 xx", name="Switch 9"}, {pattern="b1 16 xx", name="Switch 10"}, {pattern="b1 17 xx", name="Switch 11"}, {pattern="b1 18 xx", name="Switch 12"}, {pattern="b1 19 xx", name="Switch 13"}, {pattern="b1 1a xx", name="Switch 14"}, {pattern="b1 1b xx", name="Switch 15"}, {pattern="b1 1c xx", name="Switch 16"}, {pattern="b2 15 xx", name="Switch 17"}, {pattern="b2 16 xx", name="Switch 18"}, {pattern="b2 17 xx", name="Switch 19"}, {pattern="b2 18 xx", name="Switch 20"}, {pattern="b2 19 xx", name="Switch 21"}, {pattern="b2 1a xx", name="Switch 22"}, {pattern="b2 1b xx", name="Switch 23"}, {pattern="b2 1c xx", name="Switch 24"}, {pattern="b3 20 xx", name="Switch 25"}, {pattern="b3 21 xx", name="Switch 26"}, {pattern="b3 22 xx", name="Switch 27"}, {pattern="b3 23 xx", name="Switch 28"}, {pattern="b3 24 xx", name="Switch 29"}, {pattern="b3 25 xx", name="Switch 30"}, {pattern="b3 26 xx", name="Switch 31"}, {pattern="b3 27 xx", name="Switch 32"}, } remote.define_auto_outputs(outputs)
Once I hacked this into Akai’s Lua script (which was very easy to do; these files were in fact designed to be modified as we users require) I was delighted to discover that the API worked its magic and, in fact, my touch faders (and the switches underneath them!) had become fully responsive. I have no idea why Akai’s official Lua script does not contain something like this; it seems to me a tragic oversight that reduces the device’s value to less code-savvy people.
In case anyone out there owns a MAX49 and would like to try this out for themselves, I’ve prepared an alternate codec and keyboard mapping that is identical to Akai’s save for the above fix. You can download it right here. To use it, follow the same instructions Akai provides in this PDF except for one critical detail: When you set up your control surfaces in Reason’s ‘Preferences’ menu, you’ll want to select the one that says “MAX49 (Responsive)” (note the “Responsive” bit on the end there).
More Fun With Reason
The MAX49 actually has 5 separate MIDI interfaces over USB; about three of these can be used in Reason all at once, allowing your controller to act as 3 separate control surfaces (each of which can record simultaneously, be bound to specific devices on the rack, etc…). What you want to do is go into Reason’s Preferences->Keyboards & Control Surfaces menu, then set up three different control surfaces: Two “Max49 (Responsive)” surfaces whose In & Out Ports should be mapped to ‘MIDIIN1’/’MIDIOUT1’ & ‘MIDIN2’/’MIDIOUT2’ respectively, and, strangely enough, one Mackie Control device mapped to the MAX49’s ‘MIDIN4’/’MIDIOUT4’ ports. (In OS X these labels will look different, perhaps containing actual English; although I don’t own a Mac and can’t check, I suspect you’ll want to pick the first, second and fourth ones.)
Any MIDI signal that travels over channel USB A1-16 will go to the first device while anything over USB B1-16 will go the second. Any of your switches or faders set to the ‘Mackie Control’ mode will map to that third surface, giving you the option of dedicating some of your faders/switches to a separate control surface that can do it’s own thing.
What I like to do is configure my pads to use ‘B1’ and lock the second Max49 surface to a Kong device so that my pads can always play/record drums no matter what my master keyboard is up to. I also lock the Mackie surface to my mixer, dedicating two of my MAX49’s fader banks (as tricked out by Reason’s Remote Mapping system) to give me ready-to-hand access to device levels, click level, playhead position, etc…. (Then I like to compose bad music of which I am disproportionately proud.)
Brendan, I just wanted to say this MAX49 remote file of yours is brilliant. Respect.
Hi Brendan. Im looking at the MAX49 for Reason as im currently using a Novation Impulse which uses something called Automap as the intermediate translation layer and does a horrible job of it and there is no direct lua file. You might want to offer either Novation or Reason your services. One question i have is does the max 49 recognise tempo changes in Reason? This to me is a basic function but appears to be missing on the Impulse.
Hey Steve. My understanding is that the midi clock thing isn’t actually a hardware problem but is, once again, more an issue of Reason not supporting it. Only in Reason 7 do they introduce the ability to send Reason’s midi clock out to an external control surface; 6 and below can’t do this with ANY midi controller. I don’t own Reason 7, BUT since I am also curious about whether this works I will download the demo and check it out.
I’ve verified that it IS, in fact, possible to sync the MAX49’s clock to Reason! (But ONLY IN REASON 7, apparently.) It’s a three step process. 1: In your MAX49’s global settings, set the midi clock source to External. 2: In Reason, go to options->sync and check the ‘Send Midi Clock’ option. 3: Again in Reason, go to edit->preferences->advanced and in the ‘Midi clock sync’ section make sure the ‘output’ listbox is set to the MAX49.
This is also possible in FL Studio. What I would find more yet useful however is to be able to control the tempo of the DAW with its internal clock. Is there any DAW that allows this (I’m thinking of changing from FL Studio due to various other problems)?
In Reason you could remote override map the program’s tempo meter (and, if you wanted, its ‘tap for tempo’ button) to knobs or buttons on your control surface; I think this would get you pretty close.
Ah, I thought that might be the case. Unfortunately my MAX49’s Arpeggiator and Sequencer work nicer when it’s tempo is set to internal (external means the clock has to be running in the DAW for it to work which means a pattern must be playing (at least in FL Studio anyway)). Having said this I think the Cubase trial I used allowed the clock to run whilst nothing was playing – would be cool if Reason did this too (although I heard Reason doesn’t support VSTs which absolutely sucks if is the case!).
Hi Brenden , thank you so much for the midi splitting ,lol was realy doing my noggin in ! Plus the clock sync , you are my buzz of the week bro cos i found the pad and key split ok in fruity 11.But with your Reason 7 help i’m sorted for some jammin now on a’real Reason deal’.
btw i play Roland Vdrums , hooked up to the Kong , in Cubase5 ; and hey no worrys man,playing is one thing, but a decent tech head is worth his weight in gold !