I have managed to get autohotkey to send out midi messages to a music program via a midi chanel on windows. Here is how the code in case anyone needs it.
It uses the second of two channels available, the first one being some generic windows one not showing in the app.
All good so far but some additional messages should be sent via still another midi channel. the vDevice variable would be 2 for this new thing.
Any ideas?
Code: Select all
hModule := DllCall("kernel32\LoadLibrary", "Str","winmm", "Ptr")
vDeviceID := 1, hMIDIOutputDevice := 0 ; vdeviceid is the choice of midi channel
if DllCall("winmm\midiOutOpen", "Ptr*",hMIDIOutputDevice, "UInt",vDeviceID, "UPtr",0, "UPtr",0, "UInt",0, "UInt")
return
hDev := hMIDIOutputDevice
vChan := 0
;==============================
AW:= A_IsUnicode? "W": "A", A_CharSize:= A_IsUnicode? 2: 1
hWinMM:= DllCall("kernel32\LoadLibrary" AW, "Str", "Winmm.dll", "Ptr")
NumDevs:= DllCall("Winmm\midiOutGetNumDevs"), sz:= 20+32*A_CharSize
Loop, % NumDevs {
VarSetCapacity(DevCaps, sz, 0)
DllCall("Winmm\midiOutGetDevCaps" AW, "UInt", id:=A_Index-1, "Ptr", &DevCaps, "UInt", sz)
Name:= StrGet(&DevCaps+8)
DevName%A_Index%:= Name
DevNames.= id ": " Name "`n"
}
StringTrimRight, DevNames, DevNames, 1
MsgBox % DevNames
#^`::
send, ^s
reload
return
#InstallKeybdHook
#if (WinActive("ahk_class AbletonVstPlugClass") or WinActive("ahk_class Ableton Live Window Class") or WinActive("ahk_class Ableton Live 10 Suite.exe"))
{
alt & esc:: space
^s:: return
Lwin up:: return
m:: return
Lwin:: return
\::
note = 100 ; launch clip mackie
MidiNoteOn(hDev, vChan, note, 127)
MidiNoteOff(hDev, vChan, note, 127)
return
|::
note = 101 ; launch scene mackie
MidiNoteOn(hDev, vChan, note, 127)
MidiNoteOff(hDev, vChan, note, 127)
return
[::
note = 98
MidiNoteOn(hDev, vChan, note, 127) ; prev / next track mackie
MidiNoteOff(hDev, vChan, note, 127)
return
]::
note = 99
MidiNoteOn(hDev, vChan, note, 127)
MidiNoteOff(hDev, vChan, note, 127)
return
{::
note = 96
MidiNoteOn(hDev, vChan, note, 127) ; prev / next scene mackie
MidiNoteOff(hDev, vChan, note, 127)
return
}::
note = 97
MidiNoteOn(hDev, vChan, note, 127)
MidiNoteOff(hDev, vChan, note, 127)
return
/:: ; solo workaround mackie
send m
send s
send m
return
printscreen:: ; arm track workaround mackie
send m
send c
send m
return
ctrl & delete::
Send {Ctrl Down}{pgdn}{Ctrl Up}
send {right}
return
; MidiNoteOn(hDev, vChan, 76, 127) ; delete a scene
; MidiNoteOn(hDev, vChan, 86, 127) ; Loop song
; MidiNoteOn(hDev, vChan, 87, 127) ; punch in switch
; MidiNoteOn(hDev, vChan, 88, 127) ; punch out switch
; MidiNoteOn(hDev, vChan, 95, 127) ; record
; MidiNoteOn(hDev, vChan, 120, 127) ; start/stop clip
,:: Click, 349 85 ; switch to matrix
.:: Click, 349 503 ; switch to gear panel
!m:: Click, 180 65 ; metronome
^!PgUp::
MidiNoteOn(hDev, vChan, 96, 127)
MidiNoteOff(hDev, vChan, 96, 127)
return
^!PgDn::
MidiNoteOn(hDev, vChan, 97, 127)
MidiNoteOff(hDev, vChan, 97, 127)
return
lwin & insert::
loop 40 ; first scene
{
MidiNoteOn(hDev, vChan, 96, 127)
MidiNoteOff(hDev, vChan, 96 , 127)
}
return
}
#Ifwinactive
;==============================
;==============================
DllCall("winmm\midiOutClose", "Ptr",hMIDIOutputDevice, "UInt")
DllCall("kernel32\FreeLibrary", "Ptr",hModule)
;==================================================
MidiNotePlay(hMIDIOutputDevice, vChannel, vNote, vVelocity, vDuration)
{
MidiNoteOn(hMIDIOutputDevice, vChannel, vNote, vVelocity)
Sleep, % vDuration
MidiNoteOff(hMIDIOutputDevice, vChannel, vNote, 0)
}
MidiNoteOn(hMIDIOutputDevice, vChannel, vNote, vVelocity)
{
DllCall("winmm\midiOutShortMsg", "Ptr",hMIDIOutputDevice, "UInt",0x90 | vChannel | (vNote << 8) | (vVelocity << 16), "UInt")
}
MidiNoteOff(hMIDIOutputDevice, vChannel, vNote, vVelocity)
{
DllCall("winmm\midiOutShortMsg", "Ptr",hMIDIOutputDevice, "UInt",0x80 | vChannel | (vNote << 8) | (vVelocity << 16), "UInt")
}
;==================================================
MidiControlChange(hMIDIOutputDevice, Channel, ControlNo, Value)
{
DllCall("winmm\midiOutShortMsg", "UInt", hMIDIOutputDevice, "UInt", 0xB0 | Channel
| (ControlNo << 8) | (Value << 16)) ;"Control Change" event
}