Hello.
I've been wanting MIDI input for some time and given the lack of progress I had to try something myself. Ok, so I downloaded the source and thought it shouldn't need much change to implement it. But despite the heavy level of commenting in the code I couldn't quite grasp how it worked (I'd certainly like a more centralized documentation starting with an overview) as I'm not really an experienced programmer.
Next I tried Anatoly Larkin's method but couldn't quite get it work reasonably. For some reason after giving the callback function address to midiInOpen, the midi in driver almost came to a halt.
But you can make the midi driver send windows messages to the script instead of directly calling a function. Just replace the function address with a window handle and CALLBACK_FUNCTION with CALLBACK_WINDOW.
So far it seems you can't get the script's own window handle from within (let's add that to the wishlist, maybe a new built in variable.. A_ScriptHWND?), but by searching these forums I figured you can use a Gui window just as well:
Code:
Gui +LastFound
hWnd := WinExist()
So I pieced together a script that finally after realizing I need to *start* the device as well as open it

, so far works without problems.
In fact the small mistake caused me quite a headache.. I already wrote a simple dll in the hopes it would work better. Though I had never wrote a single dll before (or anything concerning midi) but fortunately it's not very complicated.
Now the dll works too and I intend to work on it, but anyway here's the ahk script using winmm.dll directly: (needs more comments, i know but i'm lazy

)
Code:
;;"#defines"
DeviceID := 0
CALLBACK_WINDOW := 0x10000
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#Persistent
Gui, +LastFound
hWnd := WinExist()
MsgBox, hWnd = %hWnd%`nPress OK to open winmm.dll library
OpenCloseMidiAPI()
OnExit, Sub_Exit
MsgBox, winmm.dll loaded.`nPress OK to open midi device`nDevice ID = %DeviceID%`nhWnd = %hWnd%`ndwFlags = CALLBACK_WINDOW
hMidiIn =
VarSetCapacity(hMidiIn, 4, 0)
result := DllCall("winmm.dll\midiInOpen", UInt,&hMidiIn, UInt,DeviceID, UInt,hWnd, UInt,0, UInt,CALLBACK_WINDOW, "UInt")
If result
{
MsgBox, error, midiInOpen returned %result%`n
GoSub, sub_exit
}
hMidiIn := NumGet(hMidiIn) ; because midiInOpen writes the value in 32 bit binary number, AHK stores it as a string
MsgBox, Midi input device opened successfully`nhMidiIn = %hMidiIn%`n`nPress OK to start the midi device
result := DllCall("winmm.dll\midiInStart", UInt,hMidiIn)
If result
{
MsgBox, error, midiInStart returned %result%`n
GoSub, sub_exit
}
; #define MM_MIM_OPEN 0x3C1 /* MIDI input */
; #define MM_MIM_CLOSE 0x3C2
; #define MM_MIM_DATA 0x3C3
; #define MM_MIM_LONGDATA 0x3C4
; #define MM_MIM_ERROR 0x3C5
; #define MM_MIM_LONGERROR 0x3C6
OnMessage(0x3C1, "midiInHandler")
OnMessage(0x3C2, "midiInHandler")
OnMessage(0x3C3, "midiInHandler")
OnMessage(0x3C4, "midiInHandler")
OnMessage(0x3C5, "midiInHandler")
OnMessage(0x3C6, "midiInHandler")
return
sub_exit:
If (hMidiIn)
DllCall("winmm.dll\midiInClose", UInt,hMidiIn)
OpenCloseMidiAPI()
ExitApp
;--------End of auto-execute section-----
;----------------------------------------
OpenCloseMidiAPI() {
Static hModule
If hModule
DllCall("FreeLibrary", UInt,hModule), hModule := ""
If (0 = hModule := DllCall("LoadLibrary",Str,"winmm.dll")) {
MsgBox Cannot load library winmm.dll
ExitApp
}
}
midiInHandler(hInput, midiMsg, wMsg)
{
statusbyte := midiMsg & 0xFF
byte1 := (midiMsg >> 8) & 0xFF
byte2 := (midiMsg >> 16) & 0xFF
ToolTip,
(
Received a message: %wMsg%
wParam = %hInput%
lParam = %midiMsg%
statusbyte = %statusbyte%
byte1 = %byte1%
byte2 = %byte2%
)
}
Esc::GoSub, sub_exit
My dll approach is a bit different. The idea was to have the dll call a specified window with messages specified separately for each input type, note/cc number and channel, and then only send messages where it's specified. And since I doubt the code tag would display c++ code properly, i put all relevant files to
http://ihme.org/~orbik/midi4ahk/
Some parts of the scripts are borrowed from various fellow ahk users, and I wish I remembered who they were.