OS X: How to Use a Gamepad as a MIDI Pitch Bend Controller

The other day I recorded some guitar in my favorite DAW, REAPER, and I was using Native Instruments’ Guitar Rig to process the raw sound straight from my pickups into the mixer.

And then I realized I wanted to add some effects to the guitar.  Such as Wah-Wah, and plus I also might want to add a pitch bend at a certain point.

DSC_0003

After googling around for a bit, I realized that I could probably use the analog sticks on my gamepad to control this MIDI and automate the effect in my DAW!

The program I used was called MidiHID.

Download MidiHID on Google Code

Now, this program (originally closed source but was open-sourced a while ago) has not been worked on for a couple years, but that doesn’t mean that it won’t work just fine to do what we need to do.

DSC_0004

When you first open MidiHID, click the plus sign in the bottom left to create a new script (or maybe one is automatically created when you open the program… can’t remember).

In the script that is created, you can use LUA code to choose how to convert and/or manipulate the data that is coming from your HID (or ‘gamepad’… by the way, HID stands for Human Interface Device).

Here is the code that I used to make one of the analog sticks in my gamepad control a midi “control change” message:

--[[
For help on MidiHID configurations or to share configurations with other MidiHID users,
visit http://http://code.google.com/p/midihid/.

The "base", "string", "table" and "math" Lua libraries are available. MidiHID provides
an extra "midi" library with the following functions:
	midi.message(message, [data1], [data2])
	midi.noteon(key, [velocity])
	midi.noteoff(key, [velocity])
	midi.controlchange(control, value)
	midi.pitchwheelchange(value)
These functions do not return anything and all their arguments are numerical values
between 0-127 (except for "message" which must be between 0-15).
Arguments in brackets are optional.

To print a message to the log area, use the log() function.
]]

function _connect()
	log("<CONNECT>")
end

-- utilities
function round(num, idp)
  local mult = 10^(idp or 0)
  return math.floor(num * mult + 0.5) / mult
end
function send_midi_note(id, value)
    if value ~= 0 then
        midi.noteon(id, 127)
    else
        midi.noteoff(id, 127)
    end
end
function minmax_wrapper(value, min, max)
    return round(((value - min) / (max - min) * 127  + 0.5), 2)
end
function topbit(value)
	if value < 63.5 then
		dothisup = value * 2
	else
		dothisup = 127
	end
	-- comment out the below line to disable my flippy
	return flippy(dothisup)
end
function flippy(value)
	return 128 - value
end
-- end utilities

-- This sends a control change message
-- which I can use to automate just about anything.
-- For example, a wah pedal in Guitar Rig!
function X(value, min, max)
    id = 1
    processthis = minmax_wrapper(value, min, max)
    midival = topbit(processthis)
    log("<thing> = " .. id .. " " .. midival)
    midi.controlchange(id, midival)
end

-- Generic "catch-all"
--function _event(name, value, min, max)
--	-- log("[" .. name .. "] = " .. value .. " (" .. min .. " | " .. max .. ")")
--	midi.controlchange(1, (value - min) / (max - min) * 127)
--end

-- Do this when the controller is disconnected
function _disconnect()
	log("<DISCONNECT>")
end

Once you have pasted this code in, hit reload script and you should be able to activate the MIDI controller in your DAW!

Note that the latency is kind of frustrating sometimes, but other than this is a great idea to use in a pinch if you don’t have access to a keyboard.

Try it, and let me know how this works for you!