├── MidiInDllTest.ahk ├── MidiInWMTest.ahk ├── README.md ├── archive └── midi_in.dll ├── dll_source ├── UpgradeLog.XML ├── UpgradeLog.htm ├── _UpgradeReport_Files │ ├── UpgradeReport.css │ ├── UpgradeReport.xslt │ ├── UpgradeReport_Error.png │ ├── UpgradeReport_Information.png │ ├── UpgradeReport_Success.png │ └── UpgradeReport_Warning.png ├── midi_in.cpp ├── midi_in.h ├── midi_in.sdf ├── midi_in.sln ├── midi_in.v11.suo ├── midi_in.vcproj ├── midi_in.vcxproj └── x64 │ └── Release64 │ ├── CL.read.1.tlog │ ├── CL.write.1.tlog │ ├── cl.command.1.tlog │ ├── link-cvtres.read.1.tlog │ ├── link-cvtres.write.1.tlog │ ├── link-rc.read.1.tlog │ ├── link-rc.write.1.tlog │ ├── link.command.1.tlog │ ├── link.read.1.tlog │ ├── link.write.1.tlog │ ├── midi_in.dll │ ├── midi_in.exp │ ├── midi_in.lastbuildstate │ ├── midi_in.lib │ ├── midi_in.log │ ├── midi_in.obj │ ├── midi_in.pdb │ ├── midi_in.unsuccessfulbuild │ ├── midi_in.write.1.tlog │ └── vc110.pdb ├── drum48.WAV ├── drum50.WAV ├── drum52.WAV ├── icon4.ico ├── midi_in.dll ├── midi_in.readme.txt ├── midi_in_lib.ahk ├── midi_in_lib_test.ahk ├── midi_keymap_template.ahk ├── wheel_vis_sample.ahk ├── winmm_sample.ahk └── worms midi key test.ahk /MidiInDllTest.ahk: -------------------------------------------------------------------------------- 1 | #NoEnv 2 | SendMode Input 3 | SetWorkingDir %A_ScriptDir% 4 | 5 | Gui +LastFound 6 | hWnd := WinExist() 7 | 8 | OpenCloseMidiDLL() 9 | OnExit, Sub_Exit 10 | 11 | result := DllCall("midi_in.dll\open", UInt,hWnd, Int,0, Int) 12 | If result 13 | { 14 | MsgBox, midi_in.dll\open(%hWnd%, %0%) returned:`n%result% 15 | GoSub, Sub_Exit 16 | } 17 | 18 | DllCall("midi_in.dll\listenWheel", Int,0, Int,0x1000) 19 | OnMessage(0x1000, "PitchWheel") 20 | OnMessage(0x200, "RemoveToolTip") ; WM_MOUSEMOVE 21 | 22 | DllCall("midi_in.dll\start") 23 | 24 | return 25 | ;--------End of auto-execute section----- 26 | ;---------------------------------------- 27 | 28 | sub_exit: 29 | OpenCloseMidiDLL() 30 | ExitApp 31 | return ; unnecessary redundancy? 32 | 33 | RemoveToolTip: 34 | SetTimer, RemoveToolTip, Off 35 | ToolTip 36 | return 37 | 38 | 39 | OpenCloseMidiDLL() { 40 | Static hModule 41 | If hModule 42 | DllCall("FreeLibrary", UInt,hModule), hModule := "" 43 | If (0 = hModule := DllCall("LoadLibrary",Str, A_ScriptDir . "\midi_in.dll")) { 44 | MsgBox Cannot load library midi_in.dll 45 | ExitApp 46 | } 47 | } 48 | 49 | 50 | PitchWheel(wParam) 51 | { 52 | ToolTip, %wParam% 53 | SetTimer, RemoveToolTip, 100 54 | } 55 | 56 | Esc::GoSub, sub_exit 57 | 58 | ^.:: 59 | value := DllCall("midi_in.dll\getChanAT", Int,1, Int) 60 | MsgBox, getChanAT(1) returned %value% 61 | 62 | return -------------------------------------------------------------------------------- /MidiInWMTest.ahk: -------------------------------------------------------------------------------- 1 | ;;"#defines" 2 | DeviceID := 0 3 | CALLBACK_WINDOW := 0x10000 4 | 5 | 6 | #NoEnv 7 | SendMode Input 8 | SetWorkingDir %A_ScriptDir% 9 | #Persistent 10 | 11 | Gui, +LastFound 12 | hWnd := WinExist() 13 | 14 | 15 | 16 | MsgBox, hWnd = %hWnd%`nPress OK to open winmm.dll library 17 | 18 | OpenCloseMidiAPI() 19 | OnExit, Sub_Exit 20 | 21 | 22 | MsgBox, winmm.dll loaded.`nPress OK to open midi device`nDevice ID = %DeviceID%`nhWnd = %hWnd%`ndwFlags = CALLBACK_WINDOW 23 | 24 | hMidiIn = 25 | VarSetCapacity(hMidiIn, 4, 0) 26 | 27 | result := DllCall("winmm.dll\midiInOpen", UInt,&hMidiIn, UInt,DeviceID, UInt,hWnd, UInt,0, UInt,CALLBACK_WINDOW, "UInt") 28 | 29 | If result 30 | { 31 | MsgBox, error, midiInOpen returned %result%`n 32 | GoSub, sub_exit 33 | } 34 | 35 | hMidiIn := NumGet(hMidiIn) ; because midiInOpen writes the value in 32 bit binary number, AHK stores it as a string 36 | 37 | 38 | MsgBox, Midi input device opened successfully`nhMidiIn = %hMidiIn%`n`nPress OK to start the midi device 39 | 40 | result := DllCall("winmm.dll\midiInStart", UInt,hMidiIn) 41 | If result 42 | { 43 | MsgBox, error, midiInStart returned %result%`n 44 | GoSub, sub_exit 45 | } 46 | 47 | 48 | ; #define MM_MIM_OPEN 0x3C1 /* MIDI input */ 49 | ; #define MM_MIM_CLOSE 0x3C2 50 | ; #define MM_MIM_DATA 0x3C3 51 | ; #define MM_MIM_LONGDATA 0x3C4 52 | ; #define MM_MIM_ERROR 0x3C5 53 | ; #define MM_MIM_LONGERROR 0x3C6 54 | 55 | OnMessage(0x3C1, "midiInHandler") 56 | OnMessage(0x3C2, "midiInHandler") 57 | OnMessage(0x3C3, "midiInHandler") 58 | OnMessage(0x3C4, "midiInHandler") 59 | OnMessage(0x3C5, "midiInHandler") 60 | OnMessage(0x3C6, "midiInHandler") 61 | 62 | return 63 | 64 | 65 | sub_exit: 66 | 67 | If (hMidiIn) 68 | DllCall("winmm.dll\midiInClose", UInt,hMidiIn) 69 | OpenCloseMidiAPI() 70 | 71 | ExitApp 72 | 73 | ;--------End of auto-execute section----- 74 | ;---------------------------------------- 75 | 76 | 77 | OpenCloseMidiAPI() { 78 | Static hModule 79 | If hModule 80 | DllCall("FreeLibrary", UInt,hModule), hModule := "" 81 | If (0 = hModule := DllCall("LoadLibrary",Str,"winmm.dll")) { 82 | MsgBox Cannot load library winmm.dll 83 | ExitApp 84 | } 85 | } 86 | 87 | 88 | 89 | midiInHandler(hInput, midiMsg, wMsg) 90 | { 91 | statusbyte := midiMsg & 0xFF 92 | byte1 := (midiMsg >> 8) & 0xFF 93 | byte2 := (midiMsg >> 16) & 0xFF 94 | 95 | ToolTip, 96 | ( 97 | Received a message: %wMsg% 98 | wParam = %hInput% 99 | lParam = %midiMsg% 100 | statusbyte = %statusbyte% 101 | byte1 = %byte1% 102 | byte2 = %byte2% 103 | ) 104 | 105 | } 106 | 107 | Esc::GoSub, sub_exit 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | A set of of utilities for using MIDI Input with AutoHotkey 2 | 3 | code gathered from this [AutoHotkey forum discussion](http://www.autohotkey.com/board/topic/28056-midi-input-library/page-1) 4 | 5 | this repo adds a 64 bit **midi_in.dll** 6 | 7 | ## 8 | 9 | [![Join the chat at https://gitter.im/micahstubbs/midi4ahk](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/micahstubbs/midi4ahk?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 10 | 11 | Here's a list of all exported functions in midi_in.dll with some explanation of how they (should)work. 12 | 13 | 14 | int open(HWND targetWindowHandle, int deviceID) 15 | 16 | targetWindowHandle should be a handle to the script itself 17 | deviceID is passed to winmm.dll\midiInOpen unchecked so you'll have to check possible values with winmm.dll\midiInGetNumDevs and winmm.dll\midiInGetDevCaps 18 | 19 | 20 | Returns: 21 | 0 - success 22 | 50 - window handle was null 23 | 60 - hMidiIn was not null 24 | anything else - error code from winmm.dll\midiInOpen 25 | 26 | 27 | 28 | int close() 29 | 30 | Closes the midi in device (unless already closed) and resets the internal midiIn handle 31 | This function must be called before openMidiIn can be called again. 32 | Unloading (detatching) the DLL automatically calls this function. 33 | 34 | 35 | void start() 36 | 37 | calls midiInStart(hMidiIn) 38 | 39 | void stop() 40 | 41 | calls midiInStop(hMidiIn) 42 | 43 | int getNumDevs() 44 | 45 | calls midiInGetNumDevs() 46 | returns the number of installed midi input devices 47 | 48 | char* getDevName(int deviceID) 49 | 50 | returns a midi input device name 51 | 52 | 53 | These are used to determine when closing and opening midi input is necessary 54 | 55 | char* getCurDevName() 56 | int getCurDevID() 57 | 58 | 59 | The midi data is sent to the ahk script with windows messages. 60 | Which messages are sent on which midi input are specified by "adding listeners". 61 | Internally these functions just write message number values in 2d and 1d arrays 62 | (e.g. notes x channels, or just channel for pitch wheel) 63 | 64 | listenNoteRange(int rangeStart, int rangeEnd, int modeFlags, int channel, int msgNumber) 65 | 66 | wParam - note number 67 | lParam - velocity (0x00 - 0x7F) 68 | 69 | rangeStart, rangeEnd 70 | midi note numbers (0x00 - 0x7F) 71 | 72 | msgNumber 73 | the (first) message number to be sent 74 | 75 | modeFlags (default = 0) 76 | & 0x01 - use increasing msgNumbers for subsequent notes 77 | & 0x02 - ignore black keys on note range 78 | & 0x04 - ignore white keys on note range 79 | 80 | channel 81 | if 0, listen to all channels (default), otherwise 1-16 82 | 83 | 84 | listenNote(int noteNumber, int channel, int msgNumber 85 | 86 | int listenCC(int ccNumber, int channel, int msgNumber) 87 | 88 | wParam - cc number (0x00 - 0x7F) 89 | lParam - cc value (0x00 - 0x7F) 90 | 91 | 92 | int listenWheel(int channel, int msgNumber) 93 | 94 | wParam - wheel position 95 | value range is 0x0000 - 0x3FFF, middle = 0x2000 96 | 97 | 98 | int listenChanAT(int channel, int msgNumber) 99 | 100 | wParam - channel aftertouch value (0x00 - 0x7F) 101 | 102 | 103 | void removeAllListeners() 104 | 105 | Resets all "listener" arrays to zero. Not really sure if this is useful. 106 | 107 | 108 | The dll also stores the most recent values of controller data even when nothing is sent forward. 109 | 110 | int getNoteOn(int noteNumber, int channel) 111 | 112 | Returns 0 if key is up, otherwise the last key down velocity 113 | 114 | int getCC(int ccNumber, int channel) 115 | int getWheel(int channel) 116 | int getChanAT(int channel) 117 | 118 | -------------------------------------------------------------------------------- /archive/midi_in.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/archive/midi_in.dll -------------------------------------------------------------------------------- /dll_source/UpgradeLog.XML: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/UpgradeLog.XML -------------------------------------------------------------------------------- /dll_source/UpgradeLog.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/UpgradeLog.htm -------------------------------------------------------------------------------- /dll_source/_UpgradeReport_Files/UpgradeReport.css: -------------------------------------------------------------------------------- 1 | /* Body style, for the entire document */ 2 | body 3 | { 4 | background: #F3F3F4; 5 | color: #1E1E1F; 6 | font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; 7 | padding: 0; 8 | margin: 0; 9 | } 10 | 11 | /* Header1 style, used for the main title */ 12 | h1 13 | { 14 | padding: 10px 0px 10px 10px; 15 | font-size: 21pt; 16 | background-color: #E2E2E2; 17 | border-bottom: 1px #C1C1C2 solid; 18 | color: #201F20; 19 | margin: 0; 20 | font-weight: normal; 21 | } 22 | 23 | /* Header2 style, used for "Overview" and other sections */ 24 | h2 25 | { 26 | font-size: 18pt; 27 | font-weight: normal; 28 | padding: 15px 0 5px 0; 29 | margin: 0; 30 | } 31 | 32 | /* Header3 style, used for sub-sections, such as project name */ 33 | h3 34 | { 35 | font-weight: normal; 36 | font-size: 15pt; 37 | margin: 0; 38 | padding: 15px 0 5px 0; 39 | background-color: transparent; 40 | } 41 | 42 | /* Color all hyperlinks one color */ 43 | a 44 | { 45 | color: #1382CE; 46 | } 47 | 48 | /* Table styles */ 49 | table 50 | { 51 | border-spacing: 0 0; 52 | border-collapse: collapse; 53 | font-size: 10pt; 54 | } 55 | 56 | table th 57 | { 58 | background: #E7E7E8; 59 | text-align: left; 60 | text-decoration: none; 61 | font-weight: normal; 62 | padding: 3px 6px 3px 6px; 63 | } 64 | 65 | table td 66 | { 67 | vertical-align: top; 68 | padding: 3px 6px 5px 5px; 69 | margin: 0px; 70 | border: 1px solid #E7E7E8; 71 | background: #F7F7F8; 72 | } 73 | 74 | /* Local link is a style for hyperlinks that link to file:/// content, there are lots so color them as 'normal' text until the user mouse overs */ 75 | .localLink 76 | { 77 | color: #1E1E1F; 78 | background: #EEEEED; 79 | text-decoration: none; 80 | } 81 | 82 | .localLink:hover 83 | { 84 | color: #1382CE; 85 | background: #FFFF99; 86 | text-decoration: none; 87 | } 88 | 89 | /* Center text, used in the over views cells that contain message level counts */ 90 | .textCentered 91 | { 92 | text-align: center; 93 | } 94 | 95 | /* The message cells in message tables should take up all avaliable space */ 96 | .messageCell 97 | { 98 | width: 100%; 99 | } 100 | 101 | /* Padding around the content after the h1 */ 102 | #content 103 | { 104 | padding: 0px 12px 12px 12px; 105 | } 106 | 107 | /* The overview table expands to width, with a max width of 97% */ 108 | #overview table 109 | { 110 | width: auto; 111 | max-width: 75%; 112 | } 113 | 114 | /* The messages tables are always 97% width */ 115 | #messages table 116 | { 117 | width: 97%; 118 | } -------------------------------------------------------------------------------- /dll_source/_UpgradeReport_Files/UpgradeReport.xslt: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | \ 36 | 37 | 38 | 39 | Solution 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | Error 87 | Warning 88 | Success 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | Message 117 | Warning 118 | Error 119 | Message 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 174 | 191 | 194 | 204 | 214 | 228 | 229 | 230 |
ProjectPathErrorsWarningsMessages
161 | 162 | 163 | 164 | _UpgradeReport_Files\UpgradeReport_Error.png 165 | _UpgradeReport_Files\UpgradeReport_Warning.png 166 | _UpgradeReport_Files\UpgradeReport_Success.png 167 | 168 | 169 | 170 | 171 | 172 | 173 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | Solution 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 192 | 193 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 215 | 216 | 217 | 218 | 219 | ' 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 |
231 |
232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | ' 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | Show additional messages 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | ' 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | Hide additional messages 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | display: none 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | _UpgradeReport_Files\UpgradeReport_Error.png 309 | _UpgradeReport_Files\UpgradeReport_Warning.png 310 | _UpgradeReport_Files\UpgradeReport_Information.png 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | : 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 |

Solution

347 |
348 | 349 |

350 | 351 |

352 |
353 |
354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 390 | 391 | 392 | 395 | 396 | 397 | 400 | 401 | 402 | 403 | 404 | 405 |
Message
388 | 389 | 393 | Solution logged no messages. 394 | 398 | logged no messages. 399 |
406 |
407 |
408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | ]]> 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | Migration Report 424 | 425 | 426 | 532 | 533 | 534 |

535 | Migration Report - 536 |

537 | 538 |
539 |

Overview

540 | 541 | 542 | 543 | 544 |
545 | 546 |
547 | 548 |

Solution and projects

549 | 550 |
551 | 552 |
553 |
554 | 555 | 556 |
557 | 558 |
-------------------------------------------------------------------------------- /dll_source/_UpgradeReport_Files/UpgradeReport_Error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/_UpgradeReport_Files/UpgradeReport_Error.png -------------------------------------------------------------------------------- /dll_source/_UpgradeReport_Files/UpgradeReport_Information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/_UpgradeReport_Files/UpgradeReport_Information.png -------------------------------------------------------------------------------- /dll_source/_UpgradeReport_Files/UpgradeReport_Success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/_UpgradeReport_Files/UpgradeReport_Success.png -------------------------------------------------------------------------------- /dll_source/_UpgradeReport_Files/UpgradeReport_Warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/_UpgradeReport_Files/UpgradeReport_Warning.png -------------------------------------------------------------------------------- /dll_source/midi_in.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "midi_in.h" 4 | 5 | #define DEVNAME_BUFFER_SIZE 100 6 | #define DEVNAME_NONE "No input" 7 | 8 | const int isBlackKey[12] = {0,1,0,1,0,0,1,0,1,0,1,0}; 9 | 10 | HMIDIIN hMidiIn = NULL; 11 | HWND hTargetWindow = NULL; 12 | int curDevID = -1; 13 | char curDevName[DEVNAME_BUFFER_SIZE] = DEVNAME_NONE; 14 | char namebuf[DEVNAME_BUFFER_SIZE]; 15 | 16 | // Every element of these arrays is a message 17 | // number to send to the target window 18 | 19 | UINT ruleNoteOn[128][16]; 20 | UINT ruleNoteOff[128][16]; 21 | UINT ruleCC[128][16]; 22 | UINT ruleWheel[16]; 23 | UINT ruleAT[16]; 24 | 25 | int minControllerDataInterval=5; 26 | 27 | int noteDown[128][16]; 28 | int ccValue[128][16]; 29 | int wheelValue[16]; 30 | int chanATValue[16]; 31 | 32 | //#define DEBUG 33 | #ifdef DEBUG 34 | void debug_output(char* string, int value1, int value2) { 35 | char buffer[4000]; 36 | sprintf(buffer, string, value1, value2); 37 | MessageBox(0,buffer,"debug output from midi_in.dll", MB_OK); 38 | } 39 | #endif 40 | BOOL WINAPI DllMain( HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved) { 41 | switch (dwReason) { 42 | case DLL_PROCESS_ATTACH: 43 | removeAllListeners(); 44 | break; 45 | 46 | case DLL_PROCESS_DETACH: 47 | stop(); 48 | close(); 49 | } 50 | return TRUE; 51 | } 52 | 53 | void CALLBACK midiInProc(HMIDIIN handle, UINT wMsg, DWORD dwInstance, DWORD midi_message, DWORD midi_timestamp) { 54 | BYTE statusbyte, byte2, byte3; 55 | UINT outMsg; 56 | if (wMsg == MIM_DATA) { 57 | statusbyte = (midi_message & 0x0000FF); 58 | byte2 = (midi_message & 0x007F00)>>8; 59 | byte3 = (midi_message & 0x7F0000)>>16; 60 | if (statusbyte > 0xEF) return; // status >= 0xF0 are machine control codes, sysex etc.. 61 | int channel = statusbyte & 0x0f; 62 | #ifdef DEBUG 63 | // debug_output("callback function called\nmidi_message = %x\nbyte2 = %i", midi_message, byte2); 64 | #endif 65 | 66 | switch (statusbyte & 0xf0) { 67 | // note off 68 | case 0x80: 69 | case0x80: // goto statement is 10 lines down. 70 | 71 | noteDown[byte2][channel] = 0; 72 | if (outMsg = ruleNoteOff[byte2][channel]) 73 | // wParam = note number, lParam = velocity 74 | PostMessage(hTargetWindow, outMsg, byte2, byte3); 75 | break; 76 | 77 | // note on 78 | case 0x90: 79 | if (byte3 == 0) goto case0x80; 80 | noteDown[byte2][channel] = byte3; 81 | if (outMsg = ruleNoteOn[byte2][channel]) 82 | // wParam = note number, lParam = velocity 83 | PostMessage(hTargetWindow, outMsg, byte2, byte3); 84 | break; 85 | 86 | // control change 87 | case 0xB0: 88 | ccValue[byte2][channel] = byte3; 89 | if (outMsg = ruleCC[byte2][channel]) 90 | // wParam = cc number, lParam = cc value 91 | PostMessage(hTargetWindow, outMsg, byte2, byte3); 92 | break; 93 | 94 | // channel aftertouch 95 | case 0xD0: 96 | chanATValue[channel] = byte2; 97 | if (outMsg = ruleAT[channel]) 98 | // wParam = ChanAT value 99 | PostMessage(hTargetWindow, outMsg, byte2, 0); 100 | break; 101 | 102 | // pitch wheel 103 | case 0xE0: 104 | wheelValue[channel] = (byte3 << 7) | byte2; 105 | if (outMsg = ruleWheel[channel]) 106 | // wParam = pitch wheel value 107 | PostMessage(hTargetWindow, outMsg, wheelValue[channel], 0); 108 | break; 109 | } 110 | } 111 | return; 112 | } 113 | 114 | extern "C" { 115 | DLLEXPORT int open(HWND hWnd, int deviceID) { 116 | MMRESULT result; 117 | if (hWnd == NULL) 118 | return 50; 119 | else hTargetWindow = hWnd; 120 | 121 | if (hMidiIn != NULL) 122 | return 60; 123 | 124 | if ((result = midiInOpen(&hMidiIn, deviceID, (DWORD_PTR)midiInProc, 0, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) 125 | return result; 126 | 127 | curDevID = deviceID; 128 | strcpy_s(curDevName, DEVNAME_BUFFER_SIZE, getDevName(curDevID)); 129 | 130 | return 0; 131 | } 132 | 133 | DLLEXPORT int close() { 134 | if (hMidiIn) { 135 | MMRESULT result = midiInClose(hMidiIn); 136 | if (result) 137 | return result; 138 | else 139 | hMidiIn = NULL; 140 | } 141 | 142 | curDevID = -1; 143 | strcpy_s(curDevName, DEVNAME_BUFFER_SIZE, DEVNAME_NONE); 144 | 145 | return 0; 146 | } 147 | DLLEXPORT void stop() { 148 | if (hMidiIn) 149 | midiInStop(hMidiIn); 150 | } 151 | DLLEXPORT void start() { 152 | #ifdef DEBUG 153 | debug_output("start() called\nhMidiIn = %x", (int)hMidiIn,0); 154 | #endif 155 | if (hMidiIn) 156 | midiInStart(hMidiIn); 157 | } 158 | 159 | 160 | 161 | /* 162 | listenNoteOnOff(rangeStart, rangeEnd, msgNumber, modeFlags=0x18, channel=0) 163 | 164 | wParam - note number 165 | lParam - velocity (0x00 - 0x7F) 166 | 167 | rangeStart, rangeEnd 168 | (0x00 - 0x7F) 169 | 170 | msgNumber 171 | the (first) message number to be captured with OnMessage() 172 | 173 | modeFlags (default = 0) 174 | & 0x01 - use increasing msgNumbers for subsequent notes, where every note increments msgNumber by either 1 or 2 (see flag 0x08) 175 | If disabled, NoteOffs make velocity=0 176 | & 0x02 - ignore black keys on note range 177 | & 0x04 - ignore white keys on note range 178 | 179 | (& 0x08) - sends NoteOffs to msgNumber 1 higher than the corresponding NoteOn (NoteOn vel=0 -> NoteOff) 180 | If disabled, send both NoteOn and NoteOff to same msgNumber, (NoteOff -> NoteOn vel=0) 181 | (& 0x10) - uses relative note numbering for wParam inside the range if flag 0x01 is not used 182 | 183 | channel 184 | if 0, listen to all channels (default), otherwise 1-16 185 | 186 | 187 | Returns: 188 | 0 - success 189 | 1 - bad note range 190 | 2 - bad channel 191 | 192 | */ 193 | DLLEXPORT int listenNoteRange(int rangeStart, int rangeEnd, int modeFlags, int channel, int msgNumber) { 194 | int firstMsgNumber = msgNumber; 195 | if (rangeStart > 127 || rangeStart < 0 || rangeEnd > 127 || rangeEnd < 0 || rangeStart > rangeEnd) 196 | return -1; 197 | 198 | if (channel < 0 || channel > 16) 199 | return -2; 200 | 201 | if ((modeFlags & 0x06) == 0x06) 202 | return 0; 203 | 204 | int blackKeyCounter = rangeStart % 12; 205 | 206 | for (int currNote = rangeStart; currNote <= rangeEnd; currNote++, blackKeyCounter++) { 207 | if (blackKeyCounter > 11) blackKeyCounter -= 12; 208 | if ((modeFlags & 0x02) && isBlackKey[blackKeyCounter]) continue; 209 | else if ((modeFlags & 0x04) && !isBlackKey[blackKeyCounter]) continue; 210 | 211 | if (channel == 0) for (int i=0; i<16; i++) { 212 | ruleNoteOn[currNote][i] = msgNumber; 213 | ruleNoteOff[currNote][i] = msgNumber; 214 | } 215 | else { 216 | ruleNoteOn[currNote][channel-1] = msgNumber; 217 | ruleNoteOff[currNote][channel-1] = msgNumber; 218 | } 219 | 220 | if (modeFlags & 0x01) msgNumber++; 221 | } 222 | return msgNumber - firstMsgNumber + 1; 223 | } 224 | 225 | DLLEXPORT int listenNote(int noteNumber, int channel, int msgNumber) { 226 | if (noteNumber < 0 || noteNumber > 127) 227 | return -1; 228 | if (channel < 0 || channel > 16) 229 | return -2; 230 | 231 | if (channel == 0) for (int i=0; i<16; i++) { 232 | ruleNoteOn[noteNumber][i] = 233 | ruleNoteOff[noteNumber][i] = msgNumber; 234 | } 235 | else { 236 | ruleNoteOn[noteNumber][channel-1] = 237 | ruleNoteOff[noteNumber][channel-1] = msgNumber; 238 | } 239 | 240 | return 0; 241 | } 242 | 243 | DLLEXPORT int listenCC(int ccNumber, int channel, int msgNumber) { 244 | if (ccNumber < 0 || ccNumber > 127) 245 | return -1; 246 | if (channel < 0 || channel > 16) 247 | return -2; 248 | 249 | if (channel == 0) for (int i=0; i<16; i++) 250 | ruleCC[ccNumber][i] = msgNumber; 251 | else 252 | ruleCC[ccNumber][channel-1] = msgNumber; 253 | return 0; 254 | } 255 | 256 | DLLEXPORT int listenWheel(int channel, int msgNumber) { 257 | if (channel < 0 || channel > 16) 258 | return -2; 259 | 260 | if (channel == 0) for (int i=0; i<16; i++) 261 | ruleWheel[i] = msgNumber; 262 | else 263 | ruleWheel[channel-1] = msgNumber; 264 | return 0; 265 | } 266 | 267 | DLLEXPORT int listenChanAT(int channel, int msgNumber) { 268 | if (channel < 0 || channel > 16) 269 | return -2; 270 | 271 | if (channel == 0) for (int i=0; i<16; i++) 272 | ruleAT[i] = msgNumber; 273 | else 274 | ruleAT[channel-1] = msgNumber; 275 | return 0; 276 | } 277 | 278 | DLLEXPORT void removeAllListeners() { 279 | for (int j=0; j<16; j++) { 280 | for (int i=0; i<128; i++) { 281 | ruleNoteOn[i][j]=0; 282 | ruleNoteOff[i][j]=0; 283 | ruleCC[i][j]=0; 284 | noteDown[i][j]=0; 285 | ccValue[i][j]=0; 286 | } 287 | ruleWheel[j]=0; 288 | ruleAT[j]=0; 289 | wheelValue[j]=0; 290 | chanATValue[j]=0; 291 | } 292 | 293 | } 294 | 295 | DLLEXPORT void setMinInterval(int minInterval) { 296 | minControllerDataInterval = minInterval; 297 | } 298 | 299 | DLLEXPORT int getNoteOn(int noteNumber, int channel) { 300 | if (noteNumber < 0 || noteNumber > 127) return -1; 301 | if (channel < 1 || channel > 16) return -2; 302 | return noteDown[noteNumber][channel-1]; 303 | } 304 | DLLEXPORT int getCC(int ccNumber, int channel) { 305 | if (ccNumber < 0 || ccNumber > 127) return -1; 306 | if (channel < 1 || channel > 16) return -2; 307 | return ccValue[ccNumber][channel-1]; 308 | } 309 | DLLEXPORT int getWheel(int channel) { 310 | if (channel < 1 || channel > 16) return -2; 311 | return wheelValue[channel-1]; 312 | } 313 | DLLEXPORT int getChanAT(int channel) { 314 | if (channel < 1 || channel > 16) return -2; 315 | return chanATValue[channel-1]; 316 | } 317 | 318 | DLLEXPORT int getNumDevs() { 319 | return midiInGetNumDevs(); 320 | } 321 | 322 | DLLEXPORT char* getDevName(int deviceID) { 323 | MIDIINCAPS caps; 324 | 325 | MMRESULT result = midiInGetDevCaps(deviceID, &caps, sizeof(caps)); 326 | if (result != MMSYSERR_NOERROR) 327 | return NULL; 328 | 329 | strcpy_s(namebuf, DEVNAME_BUFFER_SIZE, caps.szPname); 330 | return namebuf; 331 | } 332 | 333 | DLLEXPORT char* getCurDevName() { 334 | return curDevName; 335 | } 336 | 337 | DLLEXPORT int getCurDevID() { 338 | return curDevID; 339 | } 340 | 341 | } -------------------------------------------------------------------------------- /dll_source/midi_in.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define DLLEXPORT __declspec(dllexport) 4 | 5 | extern "C" { 6 | DLLEXPORT int open(HWND targetWindowHandle, int deviceID); 7 | DLLEXPORT int close(); 8 | DLLEXPORT void start(); 9 | DLLEXPORT void stop(); 10 | 11 | DLLEXPORT int getNumDevs(); 12 | DLLEXPORT char* getDevName(int deviceID); 13 | DLLEXPORT char* getCurDevName(); 14 | DLLEXPORT int getCurDevID(); 15 | 16 | DLLEXPORT int listenNoteRange(int rangeStart, int rangeEnd, int modeFlags, int channel, int msgNumber); 17 | DLLEXPORT int listenNote(int noteNumber, int channel, int msgNumber); 18 | DLLEXPORT int listenCC(int ccNumber, int channel, int msgNumber); 19 | DLLEXPORT int listenWheel(int channel, int msgNumber); 20 | DLLEXPORT int listenChanAT(int channel, int msgNumber); 21 | 22 | DLLEXPORT void setMinInterval(int minInterval); 23 | 24 | DLLEXPORT void removeAllListeners(); 25 | 26 | DLLEXPORT int getNoteOn(int noteNumber, int channel); 27 | DLLEXPORT int getCC(int ccNumber, int channel); 28 | DLLEXPORT int getWheel(int channel); 29 | DLLEXPORT int getChanAT(int channel); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /dll_source/midi_in.sdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/midi_in.sdf -------------------------------------------------------------------------------- /dll_source/midi_in.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "midi_in", "midi_in.vcxproj", "{39E771DB-61BD-4A38-BBA7-3B565B32F983}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Release|Win32 = Release|Win32 9 | Release|x64 = Release|x64 10 | Release64|Win32 = Release64|Win32 11 | Release64|x64 = Release64|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {39E771DB-61BD-4A38-BBA7-3B565B32F983}.Release|Win32.ActiveCfg = Release|Win32 15 | {39E771DB-61BD-4A38-BBA7-3B565B32F983}.Release|Win32.Build.0 = Release|Win32 16 | {39E771DB-61BD-4A38-BBA7-3B565B32F983}.Release|x64.ActiveCfg = Release|x64 17 | {39E771DB-61BD-4A38-BBA7-3B565B32F983}.Release|x64.Build.0 = Release|x64 18 | {39E771DB-61BD-4A38-BBA7-3B565B32F983}.Release64|Win32.ActiveCfg = Release64|Win32 19 | {39E771DB-61BD-4A38-BBA7-3B565B32F983}.Release64|Win32.Build.0 = Release64|Win32 20 | {39E771DB-61BD-4A38-BBA7-3B565B32F983}.Release64|x64.ActiveCfg = Release64|x64 21 | {39E771DB-61BD-4A38-BBA7-3B565B32F983}.Release64|x64.Build.0 = Release64|x64 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /dll_source/midi_in.v11.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/midi_in.v11.suo -------------------------------------------------------------------------------- /dll_source/midi_in.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 26 | 29 | 32 | 35 | 38 | 41 | 50 | 53 | 56 | 59 | 69 | 72 | 75 | 78 | 81 | 84 | 87 | 90 | 94 | 95 | 96 | 97 | 98 | 99 | 102 | 103 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /dll_source/midi_in.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Release64 6 | Win32 7 | 8 | 9 | Release64 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {39E771DB-61BD-4A38-BBA7-3B565B32F983} 23 | midiin 24 | Win32Proj 25 | 26 | 27 | 28 | DynamicLibrary 29 | v110 30 | NotSet 31 | true 32 | 33 | 34 | DynamicLibrary 35 | v110 36 | NotSet 37 | true 38 | 39 | 40 | DynamicLibrary 41 | v110 42 | NotSet 43 | true 44 | 45 | 46 | DynamicLibrary 47 | v110 48 | NotSet 49 | true 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | <_ProjectFileVersion>11.0.50727.1 69 | 70 | 71 | $(SolutionDir)$(Configuration)\ 72 | $(Configuration)_intermediate\ 73 | false 74 | 75 | 76 | false 77 | 78 | 79 | $(SolutionDir)$(Configuration)\ 80 | $(Configuration)_intermediate\ 81 | false 82 | 83 | 84 | false 85 | 86 | 87 | 88 | WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) 89 | MultiThreadedDLL 90 | 91 | Level3 92 | ProgramDatabase 93 | 94 | 95 | Winmm.lib;%(AdditionalDependencies) 96 | true 97 | Windows 98 | true 99 | true 100 | MachineX86 101 | 102 | 103 | upx -9 "$(OutDir)$(ProjectName).dll" 104 | copy "$(OutDir)$(ProjectName).dll" "C:\bin\ahk script\midi\" 105 | 106 | 107 | 108 | 109 | 110 | WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) 111 | MultiThreadedDLL 112 | 113 | 114 | Level3 115 | ProgramDatabase 116 | 117 | 118 | Winmm.lib;%(AdditionalDependencies) 119 | true 120 | Windows 121 | true 122 | true 123 | 124 | 125 | upx -9 "$(OutDir)$(ProjectName).dll" 126 | copy "$(OutDir)$(ProjectName).dll" "C:\bin\ahk script\midi\" 127 | 128 | 129 | 130 | 131 | 132 | WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) 133 | MultiThreadedDLL 134 | 135 | 136 | Level3 137 | ProgramDatabase 138 | 139 | 140 | Winmm.lib;%(AdditionalDependencies) 141 | true 142 | Windows 143 | true 144 | true 145 | MachineX86 146 | 147 | 148 | upx -9 "$(OutDir)$(ProjectName).dll" 149 | copy "$(OutDir)$(ProjectName).dll" "C:\bin\ahk script\midi\" 150 | 151 | 152 | 153 | 154 | 155 | WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) 156 | MultiThreadedDLL 157 | 158 | 159 | Level3 160 | ProgramDatabase 161 | 162 | 163 | Winmm.lib;%(AdditionalDependencies) 164 | true 165 | Windows 166 | true 167 | true 168 | 169 | 170 | upx -9 "$(OutDir)$(ProjectName).dll" 171 | copy "$(OutDir)$(ProjectName).dll" "C:\bin\ahk script\midi\" 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /dll_source/x64/Release64/CL.read.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/CL.read.1.tlog -------------------------------------------------------------------------------- /dll_source/x64/Release64/CL.write.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/CL.write.1.tlog -------------------------------------------------------------------------------- /dll_source/x64/Release64/cl.command.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/cl.command.1.tlog -------------------------------------------------------------------------------- /dll_source/x64/Release64/link-cvtres.read.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/link-cvtres.read.1.tlog -------------------------------------------------------------------------------- /dll_source/x64/Release64/link-cvtres.write.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/link-cvtres.write.1.tlog -------------------------------------------------------------------------------- /dll_source/x64/Release64/link-rc.read.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/link-rc.read.1.tlog -------------------------------------------------------------------------------- /dll_source/x64/Release64/link-rc.write.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/link-rc.write.1.tlog -------------------------------------------------------------------------------- /dll_source/x64/Release64/link.command.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/link.command.1.tlog -------------------------------------------------------------------------------- /dll_source/x64/Release64/link.read.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/link.read.1.tlog -------------------------------------------------------------------------------- /dll_source/x64/Release64/link.write.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/link.write.1.tlog -------------------------------------------------------------------------------- /dll_source/x64/Release64/midi_in.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/midi_in.dll -------------------------------------------------------------------------------- /dll_source/x64/Release64/midi_in.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/midi_in.exp -------------------------------------------------------------------------------- /dll_source/x64/Release64/midi_in.lastbuildstate: -------------------------------------------------------------------------------- 1 | #v4.0:v110:false 2 | Release64|x64|C:\ahk\midi4ahk\dll_source\| 3 | -------------------------------------------------------------------------------- /dll_source/x64/Release64/midi_in.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/midi_in.lib -------------------------------------------------------------------------------- /dll_source/x64/Release64/midi_in.log: -------------------------------------------------------------------------------- 1 | Build started 2/7/2015 2:02:19 PM. 2 | 1>Project "C:\ahk\midi4ahk\dll_source\midi_in.vcxproj" on node 2 (Build target(s)). 3 | 1>ClCompile: 4 | C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\x86_amd64\CL.exe /c /Zi /nologo /W3 /WX- /O2 /GL /D WIN32 /D NDEBUG /D _WINDOWS /D _USRDLL /D _CRT_SECURE_NO_DEPRECATE /D _WINDLL /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"x64\Release64\\" /Fd"x64\Release64\vc110.pdb" /Gd /TP /errorReport:prompt midi_in.cpp 5 | midi_in.cpp 6 | 1>midi_in.cpp(59): warning C4244: '=' : conversion from 'DWORD' to 'BYTE', possible loss of data 7 | Link: 8 | C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\x86_amd64\link.exe /ERRORREPORT:PROMPT /OUT:"C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.dll" /INCREMENTAL:NO /NOLOGO Winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.pdb" /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.lib" /MACHINE:X64 /DLL x64\Release64\midi_in.obj 9 | Creating library C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.lib and object C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.exp 10 | Generating code 11 | Finished generating code 12 | midi_in.vcxproj -> C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.dll 13 | PostBuildEvent: 14 | upx -9 "C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.dll" 15 | copy "C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.dll" "C:\bin\ahk script\midi\" 16 | 17 | :VCEnd 18 | 'upx' is not recognized as an internal or external command, 19 | operable program or batch file. 20 | The system cannot find the path specified. 21 | 0 file(s) copied. 22 | 1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppCommon.targets(134,5): error MSB3073: The command "upx -9 "C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.dll" 23 | C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppCommon.targets(134,5): error MSB3073: copy "C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.dll" "C:\bin\ahk script\midi\" 24 | C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppCommon.targets(134,5): error MSB3073: 25 | C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppCommon.targets(134,5): error MSB3073: :VCEnd" exited with code 1. 26 | 1>Done Building Project "C:\ahk\midi4ahk\dll_source\midi_in.vcxproj" (Build target(s)) -- FAILED. 27 | 28 | Build FAILED. 29 | 30 | Time Elapsed 00:00:01.85 31 | -------------------------------------------------------------------------------- /dll_source/x64/Release64/midi_in.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/midi_in.obj -------------------------------------------------------------------------------- /dll_source/x64/Release64/midi_in.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/midi_in.pdb -------------------------------------------------------------------------------- /dll_source/x64/Release64/midi_in.unsuccessfulbuild: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/midi_in.unsuccessfulbuild -------------------------------------------------------------------------------- /dll_source/x64/Release64/midi_in.write.1.tlog: -------------------------------------------------------------------------------- 1 | ^C:\ahk\midi4ahk\dll_source\midi_in.vcxproj 2 | C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.lib 3 | C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.lib 4 | C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.exp 5 | C:\ahk\midi4ahk\dll_source\x64\Release64\midi_in.exp 6 | -------------------------------------------------------------------------------- /dll_source/x64/Release64/vc110.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/dll_source/x64/Release64/vc110.pdb -------------------------------------------------------------------------------- /drum48.WAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/drum48.WAV -------------------------------------------------------------------------------- /drum50.WAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/drum50.WAV -------------------------------------------------------------------------------- /drum52.WAV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/drum52.WAV -------------------------------------------------------------------------------- /icon4.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/icon4.ico -------------------------------------------------------------------------------- /midi_in.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micahstubbs/midi4ahk/f99d12f17894a413e806d9cc41bdd365bd8be439/midi_in.dll -------------------------------------------------------------------------------- /midi_in.readme.txt: -------------------------------------------------------------------------------- 1 | Here's a list of all exported functions in midi_in.dll with some explanation of how they (should)work. 2 | 3 | 4 | 5 | 6 | int open(HWND targetWindowHandle, int deviceID) 7 | 8 | targetWindowHandle should be a handle to the script itself 9 | deviceID is passed to winmm.dll\midiInOpen unchecked so you'll have to check possible values with winmm.dll\midiInGetNumDevs and winmm.dll\midiInGetDevCaps 10 | 11 | 12 | Returns: 13 | 0 - success 14 | 50 - window handle was null 15 | 60 - hMidiIn was not null 16 | anything else - error code from winmm.dll\midiInOpen 17 | 18 | 19 | 20 | int close() 21 | 22 | Closes the midi in device (unless already closed) and resets the internal midiIn handle 23 | This function must be called before openMidiIn can be called again. 24 | Unloading (detatching) the DLL automatically calls this function. 25 | 26 | 27 | void start() 28 | 29 | calls midiInStart(hMidiIn) 30 | 31 | void stop() 32 | 33 | calls midiInStop(hMidiIn) 34 | 35 | int getNumDevs() 36 | 37 | calls midiInGetNumDevs() 38 | returns the number of installed midi input devices 39 | 40 | char* getDevName(int deviceID) 41 | 42 | returns a midi input device name 43 | 44 | 45 | These are used to determine when closing and opening midi input is necessary 46 | 47 | char* getCurDevName() 48 | int getCurDevID() 49 | 50 | 51 | The midi data is sent to the ahk script with windows messages. 52 | Which messages are sent on which midi input are specified by "adding listeners". 53 | Internally these functions just write message number values in 2d and 1d arrays 54 | (e.g. notes x channels, or just channel for pitch wheel) 55 | 56 | listenNoteRange(int rangeStart, int rangeEnd, int modeFlags, int channel, int msgNumber) 57 | 58 | wParam - note number 59 | lParam - velocity (0x00 - 0x7F) 60 | 61 | rangeStart, rangeEnd 62 | midi note numbers (0x00 - 0x7F) 63 | 64 | msgNumber 65 | the (first) message number to be sent 66 | 67 | modeFlags (default = 0) 68 | & 0x01 - use increasing msgNumbers for subsequent notes 69 | & 0x02 - ignore black keys on note range 70 | & 0x04 - ignore white keys on note range 71 | 72 | channel 73 | if 0, listen to all channels (default), otherwise 1-16 74 | 75 | 76 | listenNote(int noteNumber, int channel, int msgNumber 77 | 78 | int listenCC(int ccNumber, int channel, int msgNumber) 79 | 80 | wParam - cc number (0x00 - 0x7F) 81 | lParam - cc value (0x00 - 0x7F) 82 | 83 | 84 | int listenWheel(int channel, int msgNumber) 85 | 86 | wParam - wheel position 87 | value range is 0x0000 - 0x3FFF, middle = 0x2000 88 | 89 | 90 | int listenChanAT(int channel, int msgNumber) 91 | 92 | wParam - channel aftertouch value (0x00 - 0x7F) 93 | 94 | 95 | void removeAllListeners() 96 | 97 | Resets all "listener" arrays to zero. Not really sure if this is useful. 98 | 99 | 100 | The dll also stores the most recent values of controller data even when nothing is sent forward. 101 | 102 | int getNoteOn(int noteNumber, int channel) 103 | 104 | Returns 0 if key is up, otherwise the last key down velocity 105 | 106 | int getCC(int ccNumber, int channel) 107 | int getWheel(int channel) 108 | int getChanAT(int channel) -------------------------------------------------------------------------------- /midi_in_lib.ahk: -------------------------------------------------------------------------------- 1 | midi_in_Open(defaultDevID = -1) 2 | { 3 | global 4 | if ((midi_in_hModule := DllCall("LoadLibrary", Str,A_ScriptDir . "\midi_in.dll")) == 0) 5 | { 6 | MsgBox "Cannot load library midi_in.dll" 7 | return 1 8 | } 9 | if (defaultDevID >= DllCall("midi_in.dll\getNumDevs")) 10 | defaultDevID := -1 11 | 12 | midi_in_MakeTrayMenu(defaultDevID) 13 | if (defaultDevID >= 0) 14 | midi_in_OpenDevice(defaultDevID) 15 | return 0 16 | } 17 | 18 | midi_in_MakeTrayMenu(defaultDevID) 19 | { 20 | numDevs := DllCall("midi_in.dll\getNumDevs") 21 | global midi_in_lastSelectedMenuItem 22 | 23 | Menu devNameMenu, Add, No input, sub_menu_openinput 24 | Menu devNameMenu, Add ; separator 25 | if (defaultDevID < 0) 26 | midi_in_lastSelectedMenuItem := "No Input" 27 | 28 | loop %numDevs% 29 | { 30 | devID := A_Index-1 31 | if ((devName := DllCall("midi_in.dll\getDevName", Int,devID, Str)) == 0) 32 | { 33 | MsgBox, Error in creating midi input device list 34 | return 1 35 | } 36 | Menu devNameMenu, Add, %devName%, sub_menu_openinput 37 | if (devID == defaultDevID) 38 | { 39 | Menu devNameMenu, Check, %devName% 40 | midi_in_lastSelectedMenuItem := devName 41 | } 42 | } 43 | Menu TRAY, Add, MIDI-in device, :devNameMenu 44 | } 45 | 46 | sub_menu_openinput: 47 | midi_in_OpenDevice(A_ThisMenuItemPos-3) 48 | ; Move the check mark to new position 49 | Menu %A_ThisMenu%, Check, %A_ThisMenuItem% 50 | Menu %A_ThisMenu%, Uncheck, %midi_in_lastSelectedMenuItem% 51 | midi_in_lastSelectedMenuItem := A_ThisMenuItem 52 | return 53 | 54 | midi_in_OpenDevice(deviceID) ;deviceID < 0 means no input 55 | { 56 | Critical 57 | midi_in_Stop() 58 | 59 | Gui +LastFound 60 | hWnd := WinExist() 61 | 62 | curDevID := DllCall("midi_in.dll\getCurDevID", Int) 63 | if (deviceID == curDevID) 64 | return 0 65 | if (curDevID >= 0) 66 | result := DllCall("midi_in.dll\close") 67 | if (result) 68 | { 69 | MsgBox Error closing midi device`nmidi_in.dll\close returned %result% 70 | return 1 71 | } 72 | if (deviceID < 0) 73 | return 0 74 | 75 | result := DllCall("midi_in.dll\open", UInt,hWnd, Int,deviceID, Int) 76 | if (result) 77 | { 78 | MsgBox Error opening midi device`nmidi_in.dll\open(%hWnd%, %deviceID%) returned %result% 79 | return 1 80 | } 81 | ; MsgBox Press OK to start midi input 82 | midi_in_Start() 83 | return 0 84 | } 85 | 86 | midi_in_Close() 87 | { 88 | global 89 | if (midi_in_hModule) 90 | DllCall("FreeLibrary", UInt,midi_in_hModule), midi_in_hModule := "" 91 | } 92 | 93 | midi_in_Start() 94 | { 95 | DllCall("midi_in.dll\start") 96 | } 97 | 98 | midi_in_Stop() 99 | { 100 | DllCall("midi_in.dll\stop") 101 | } 102 | 103 | listenNote(noteNumber, funcName, channel=0) 104 | { 105 | global msgNum 106 | GoSub, sub_increase_msgnum 107 | DllCall("midi_in.dll\listenNote", Int,noteNumber, Int,channel, Int,msgNum) 108 | OnMessage(msgNum, funcName) 109 | } 110 | 111 | listenNoteRange(rangeStart, rangeEnd, funcName, flags=0, channel=0) 112 | { 113 | global msgNum 114 | GoSub, sub_increase_msgnum 115 | msgCount := DllCall("midi_in.dll\listenNoteRange", int,rangeStart, int,rangeEnd, int,(flags & 0x07), int,channel, int,msgNum) 116 | 117 | 118 | if (msgCount <= 0) 119 | return 120 | if (flags & 0x01) 121 | loop %msgCount% 122 | { 123 | OnMessage(msgNum, funcName . A_Index) 124 | GoSub, sub_increase_msgnum 125 | } 126 | else 127 | OnMessage(msgNum, funcName) 128 | } 129 | 130 | listenCC(ccNumber, funcName, channel=0) 131 | { 132 | global msgNum 133 | GoSub, sub_increase_msgnum 134 | DllCall("midi_in.dll\listenCC", Int,ccNumber, Int,channel, Int,msgNum) 135 | OnMessage(msgNum, funcName) 136 | } 137 | 138 | listenWheel(funcName, channel=0) 139 | { 140 | global msgNum 141 | GoSub, sub_increase_msgnum 142 | DllCall("midi_in.dll\listenWheel", Int,channel, Int,msgNum) 143 | OnMessage(msgNum, funcName) 144 | } 145 | 146 | listenChanAT(funcName, channel=0) 147 | { 148 | global msgNum 149 | GoSub, sub_increase_msgnum 150 | DllCall("midi_in.dll\listenChanAT", Int,channel, Int,msgNum) 151 | OnMessage(msgNum, funcName) 152 | } 153 | 154 | 155 | getNoteOn(noteNumber, channel) 156 | { 157 | return DllCall("midi_in.dll\getNoteOn", Int,noteNumber, Int,channel) 158 | } 159 | 160 | getCC(ccNumber, channel) 161 | { 162 | return DllCall("midi_in.dll\getCC", Int,ccNumber, Int,channel) 163 | } 164 | 165 | getWheel(channel) 166 | { 167 | return DllCall("midi_in.dll\getWheel", Int,channel) 168 | } 169 | 170 | getChanAT(channel) 171 | { 172 | return DllCall("midi_in.dll\getChanAT", Int,channel) 173 | } 174 | 175 | sub_increase_msgnum: 176 | if msgNum 177 | msgNum++ 178 | else 179 | msgNum := 0x2000 180 | return -------------------------------------------------------------------------------- /midi_in_lib_test.ahk: -------------------------------------------------------------------------------- 1 | #SingleInstance force 2 | SendMode Input 3 | SetWorkingDir %A_ScriptDir% 4 | 5 | OnExit, sub_exit 6 | if (midi_in_Open(0)) 7 | ExitApp 8 | Menu TRAY, Icon, icon4.ico 9 | 10 | ;-------------------- Midi "hotkey" mappings ----------------------- 11 | listenNoteRange(48, 52, "playSomeSounds", 0x02) 12 | 13 | return 14 | ;----------------------End of auto execute section-------------------- 15 | 16 | sub_exit: 17 | midi_in_Close() 18 | ExitApp 19 | 20 | ;-------------------------Miscellaneous hotkeys----------------------- 21 | Esc::ExitApp 22 | 23 | ;-------------------------Midi "hotkey" functions--------------------- 24 | playSomeSounds(note, vel) 25 | { 26 | if (vel) ; vel == 0 means note off 27 | { 28 | SoundPlay drum%note%.wav 29 | } 30 | } 31 | 32 | ;------------------------- Midi input library ---------------------- 33 | #include midi_in_lib.ahk 34 | -------------------------------------------------------------------------------- /midi_keymap_template.ahk: -------------------------------------------------------------------------------- 1 | SendMode Input 2 | SetWorkingDir %A_ScriptDir% 3 | 4 | OnExit, sub_exit 5 | if (midi_in_Open(0)) 6 | ExitApp 7 | 8 | ;-------------------- Midi "hotkey" mappings ----------------------- 9 | listenNote(55, "space") 10 | 11 | listenNote(36, "note36") 12 | listenNote(37, "note37") 13 | listenNote(38, "note38") 14 | listenNote(39, "note39") 15 | listenNote(40, "note40") 16 | listenNote(41, "note41") 17 | listenNote(42, "note42") 18 | listenNote(43, "note43") 19 | listenNote(44, "note44") 20 | listenNote(45, "note45") 21 | listenNote(46, "note46") 22 | listenNote(47, "note47") 23 | listenNote(48, "note48") 24 | listenNote(49, "note49") 25 | listenNote(50, "note50") 26 | listenNote(51, "note51") 27 | listenNote(52, "note52") 28 | listenNote(53, "note53") 29 | listenNote(54, "note54") 30 | listenNote(55, "note55") 31 | listenNote(56, "note56") 32 | listenNote(57, "note57") 33 | listenNote(58, "note58") 34 | listenNote(59, "note59") 35 | listenNote(60, "note60") 36 | listenNote(61, "note61") 37 | listenNote(62, "note62") 38 | listenNote(63, "note63") 39 | listenNote(64, "note64") 40 | listenNote(65, "note65") 41 | listenNote(66, "note66") 42 | listenNote(67, "note67") 43 | listenNote(68, "note68") 44 | listenNote(69, "note69") 45 | listenNote(70, "note70") 46 | listenNote(71, "note71") 47 | listenNote(72, "note72") 48 | listenNote(73, "note73") 49 | listenNote(74, "note74") 50 | listenNote(75, "note75") 51 | listenNote(76, "note76") 52 | listenNote(77, "note77") 53 | listenNote(78, "note78") 54 | listenNote(79, "note79") 55 | listenNote(80, "note80") 56 | listenNote(81, "note81") 57 | listenNote(82, "note82") 58 | listenNote(83, "note83") 59 | listenNote(84, "note84") 60 | 61 | return 62 | ;----------------------End of auto execute section-------------------- 63 | 64 | sub_exit: 65 | midi_in_Close() 66 | ExitApp 67 | 68 | ;-------------------------Miscellaneous hotkeys----------------------- 69 | Esc::ExitApp 70 | 71 | ;-------------------------Midi "hotkey" functions--------------------- 72 | space(note, vel) 73 | { 74 | if (vel) 75 | Send {Space down} 76 | else 77 | Send {Space up} 78 | } 79 | 80 | note36(note, vel) 81 | { 82 | if (vel) 83 | Send {Enter}{Tab 2}THE WITNESS:*.{Space 2} 84 | ;else 85 | ;Send {} 86 | } 87 | 88 | note38(note, vel) 89 | { 90 | if (vel) 91 | Send {Enter}{Tab 2}THE COURT:*.{Space 2} 92 | } 93 | 94 | 95 | note40(note, vel) 96 | { 97 | if (vel) 98 | Send {Enter}{Tab 2}ATTY A:*.{Space 2} 99 | } 100 | 101 | 102 | note41(note, vel) 103 | { 104 | if (vel) 105 | Send {Enter}{Tab 2}ATTY B:*.{Space 2} 106 | } 107 | 108 | 109 | note43(note, vel) 110 | { 111 | if (vel) 112 | Send {Enter}{Tab 2}ATTY C:*.{Space 2} 113 | } 114 | 115 | note45(note, vel) 116 | { 117 | if (vel) 118 | Send {Enter}{Tab 2}ATTY D:*.{Space 2} 119 | } 120 | 121 | note47(note, vel) 122 | { 123 | if (vel) 124 | Send {Enter} {Tab 2}BY ATTY A:*. 125 | } 126 | 127 | note48(note, vel) 128 | { 129 | if (vel) 130 | Send {Enter}{Tab 2}BY ATTY B:*. 131 | } 132 | 133 | note50(note, vel) 134 | { 135 | if (vel) 136 | Send {Enter} {Tab 2}BY ATTY C:*. 137 | } 138 | 139 | note52(note, vel) 140 | { 141 | if (vel) 142 | Send {Enter} {Tab 2}BY ATTY D:*. 143 | } 144 | 145 | note53(note, vel) 146 | { 147 | if (vel) 148 | Send {Enter} {Tab 2} Q:*. 149 | } 150 | 151 | note55(note, vel) 152 | { 153 | if (vel) 154 | Send {Enter} {Tab 2} A:*. 155 | } 156 | 157 | note57(note, vel) 158 | { 159 | if (vel) 160 | Send . {Enter} {Tab 2}Q:*. 161 | } 162 | 163 | note59(note, vel) 164 | { 165 | if (vel) 166 | Send ? {Enter} {Tab 2}Q:*. 167 | } 168 | 169 | 170 | ;------------------------- Midi input library ---------------------- 171 | #include midi_in_lib.ahk -------------------------------------------------------------------------------- /wheel_vis_sample.ahk: -------------------------------------------------------------------------------- 1 | ; 2 | ; AutoHotkey Version: 1.0.47.x 3 | ; Language: English 4 | ; Platform: Win9x/NT 5 | ; Author: Dabbler, edit from stuff by ribbet.1 and others 6 | ; 7 | ; Script Function: 8 | ; Reads values from wheel and CC1 and displays them as progressbars 9 | ; midi in, select device from shortcut menu, needs midi_in_lib.ahk and midi_in.dll in folder 10 | ; 11 | SendMode Input 12 | SetWorkingDir %A_ScriptDir% 13 | #SingleInstance, Force 14 | 15 | Gui, -Caption +Border +ToolWindow 16 | Gui, Color, EEAA99 17 | Gui, +LastFound 18 | WinSet, TransColor, EEAA99 19 | Gui, Add, Progress, w384 h10 cBlue -0x1 Range0-127 vbar_X ; value goes upto 127, bar length is 384 20 | Gui, Add, Progress, x+10 w384 h10 cRed -0x1 Range0-16384 vbar_Y ; value goes upto 16384 (my CC1 controller's output), bar length is 384 21 | Gui, Show, x5 y707 , W_Meter ; position and show, Adjust X & Y to suit your screen res 22 | 23 | OnExit, sub_exit 24 | if (midi_in_Open(0)) 25 | ExitApp 26 | 27 | ;-------------------- Midi "hotkey" mappings ----------------------- 28 | 29 | listenCC(1, "do_cc_one", 0) 30 | listenWheel("do_wheel", 0) 31 | return 32 | ;----------------------End of auto execute section-------------------- 33 | 34 | sub_exit: 35 | midi_in_Close() 36 | ExitApp 37 | 38 | ;-------------------------Miscellaneous hotkeys----------------------- 39 | Esc::ExitApp 40 | 41 | ;---------------------------------------------- 42 | ;experiment 43 | 44 | do_cc_one(ccnumber, ccvel) 45 | { 46 | if (ccvel) 47 | { 48 | left_bar := ccvel 49 | GuiControl,, bar_X, %left_bar% 50 | ; ccvel is the value 51 | 52 | } 53 | } 54 | 55 | 56 | do_wheel(wheelin) 57 | { 58 | right_bar := wheelin 59 | GuiControl,, bar_Y, %right_bar% 60 | ; wheelin is the value 61 | 62 | } 63 | ;------------------------- Midi input library ---------------------- 64 | #include midi_in_lib.ahk -------------------------------------------------------------------------------- /winmm_sample.ahk: -------------------------------------------------------------------------------- 1 | /* 2 | This code is written by orbik and others, 3 | I somewhat hacked it. 4 | 5 | 1. Try this just using the tool tip first, when that makes sense, comment the tool tip out 6 | 7 | 2. Then Uncomment the lines at 112 for sending text 8 | - TAKES A MIDI NOTE AND CONVERTS IT TO A KEYPRESS. 9 | - IT WILL SEND NOTE ON TEXT WHEN NOTE 60 (MIDILE c) AND 10 | */ 11 | 12 | ;;"#defines" 13 | 14 | ; SET THIS DEVICEiD TO YOUR MIDI INPUT PORT, 0 IS THE FIRST MIDI PORT, 15 | ; IF YOU DON'T KNOW THE MIDI PORT USE MIDIOX TO FIND OUT. 16 | DeviceID := 8 17 | CALLBACK_WINDOW := 0x10000 18 | 19 | #NoEnv 20 | SendMode Input 21 | SetWorkingDir %A_ScriptDir% 22 | #Persistent 23 | 24 | Gui, +LastFound 25 | hWnd := WinExist() 26 | 27 | ;MsgBox, hWnd = %hWnd%`nPress OK to open winmm.dll library 28 | 29 | OpenCloseMidiAPI() 30 | OnExit, Sub_Exit 31 | 32 | ;MsgBox, winmm.dll loaded.`nPress OK to open midi device`nDevice ID = %DeviceID%`nhWnd = %hWnd%`ndwFlags = CALLBACK_WINDOW 33 | 34 | hMidiIn = 35 | VarSetCapacity(hMidiIn, 4, 0) 36 | 37 | result := DllCall("winmm.dll\midiInOpen", UInt,&hMidiIn, UInt,DeviceID, UInt,hWnd, UInt,0, UInt,CALLBACK_WINDOW, "UInt") 38 | 39 | If result 40 | { 41 | MsgBox, error, midiInOpen returned %result%`n 42 | GoSub, sub_exit 43 | } 44 | 45 | hMidiIn := NumGet(hMidiIn) ; because midiInOpen writes the value in 32 bit binary number, AHK stores it as a string 46 | 47 | 48 | ;MsgBox, Midi input device opened successfully`nhMidiIn = %hMidiIn%`n`nPress OK to start the midi device 49 | 50 | result := DllCall("winmm.dll\midiInStart", UInt,hMidiIn) 51 | If result 52 | { 53 | MsgBox, error, midiInStart returned %result%`n 54 | GoSub, sub_exit 55 | } 56 | 57 | 58 | ; #define MM_MIM_OPEN 0x3C1 /* MIDI input */ 59 | ; #define MM_MIM_CLOSE 0x3C2 60 | ; #define MM_MIM_DATA 0x3C3 61 | ; #define MM_MIM_LONGDATA 0x3C4 62 | ; #define MM_MIM_ERROR 0x3C5 63 | ; #define MM_MIM_LONGERROR 0x3C6 64 | 65 | OnMessage(0x3C1, "midiInHandler") ; calling the function below 66 | OnMessage(0x3C2, "midiInHandler") 67 | OnMessage(0x3C3, "midiInHandler") 68 | OnMessage(0x3C4, "midiInHandler") 69 | OnMessage(0x3C5, "midiInHandler") 70 | OnMessage(0x3C6, "midiInHandler") 71 | 72 | return 73 | 74 | ;--------End of auto-execute section----- 75 | 76 | ; =============== this will exit the app when esc is pushed 77 | 78 | sub_exit: 79 | 80 | If (hMidiIn) 81 | DllCall("winmm.dll\midiInClose", UInt,hMidiIn) 82 | OpenCloseMidiAPI() 83 | 84 | ExitApp 85 | 86 | 87 | 88 | OpenCloseMidiAPI() ; calls the winmm.dll to close midi port 89 | { 90 | Static hModule 91 | If hModule 92 | DllCall("FreeLibrary", UInt,hModule), hModule := "" 93 | If (0 = hModule := DllCall("LoadLibrary",Str,"winmm.dll")) 94 | { 95 | MsgBox Cannot load library winmm.dll 96 | ExitApp 97 | } 98 | } 99 | 100 | 101 | midiInHandler(hInput, midiMsg, wMsg) ; THIS IS THE MIDI IN FUNCTION WHERE THE MIDI MESSAGE IS BROKEN UP 102 | { 103 | statusbyte := midiMsg & 0xFF ; EXTRACT THE STATUS BYTE (WHAT KIND OF MIDI MESSAGE IS IT) 104 | chan := (statusbyte & 0x0f) + 1 ; WHAT MIDI CHANNEL IS THE MESSAGE ON? 105 | byte1 := (midiMsg >> 8) & 0xFF ; THIS IS DATA1 VALUE = NOTE NUMBER OR CC NUMBER 106 | byte2 := (midiMsg >> 16) & 0xFF ; DATA2 VALUE IS NOTE VELEOCITY OR CC VALUE 107 | 108 | 109 | ;THIS SECTION WILL SEND TEXT - OPEN NOTEPAD AND GIVE IT FOCUS WITH THIS RUNNING 110 | ;UNCOMMENT THIS SECTION BELOW TO HAVE THE midi note >TEXT ;SENT. 111 | 112 | /* 113 | If ((byte1 = 60) & (statusbyte = 144)) ; test note number and status for Note ON (144) and note number middle C 114 | { 115 | send, Note %byte1% on, ; TYPES TEXT WITH THE NOTE NUMBER VAR. 116 | } 117 | Else if ((byte1 = 60) & (statusbyte = 128)) ; test for note off 118 | { 119 | send, Note %byte1% off 120 | } 121 | 122 | ; Just trying the same idea on a different note a differnt way 123 | If (byte1 = 62) ; test for note 62 - attempt at splitting the test up 124 | { 125 | if (statusbyte = 144) ; is the note above on? 126 | { 127 | send, Note %byte1% on 128 | } 129 | Else if (statusbyte = 128) ; is the note off 130 | { 131 | send, Note %byte1% off 132 | } 133 | } 134 | */ 135 | 136 | ;AFTER YOU PLAY WITH THIS FOR A LITTLE WHILE AND SEE IT WORK COMMENT THIS OUT OR USE IT FOR KNOWING WHAT MESSAGES ARE DOING 137 | 138 | ;/* 139 | ToolTip, ; THIS WILL SHOW A TOOL TIP OF THE MIDI DATA FROM EACH KEYPRESS OR CC PRESS. 140 | ( 141 | Received a message: %wMsg% 142 | wParam = %hInput% 143 | lParam = %midiMsg% 144 | statusbyte = %statusbyte% 145 | chan = %chan% 146 | byte1 = %byte1% 147 | byte2 = %byte2% 148 | ) 149 | ; */ 150 | 151 | } 152 | Return 153 | 154 | Esc::GoSub, sub_exit 155 | 156 | /* 157 | below is written by orbik 158 | 159 | 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/ 160 | 161 | Some parts of the scripts are borrowed from various fellow ahk users, and I wish I remembered who they were. 162 | */ -------------------------------------------------------------------------------- /worms midi key test.ahk: -------------------------------------------------------------------------------- 1 | SendMode Input 2 | SetWorkingDir %A_ScriptDir% 3 | 4 | OnExit, sub_exit 5 | if (midi_in_Open(0)) 6 | ExitApp 7 | 8 | ;-------------------- Midi "hotkey" mappings ----------------------- 9 | listenNote(55, "space") 10 | 11 | listenNote(60, "note60") 12 | listenNote(62, "note62") 13 | listenNote(63, "note63") 14 | listenNote(64, "note64") 15 | 16 | return 17 | ;----------------------End of auto execute section-------------------- 18 | 19 | sub_exit: 20 | midi_in_Close() 21 | ExitApp 22 | 23 | ;-------------------------Miscellaneous hotkeys----------------------- 24 | Esc::ExitApp 25 | 26 | ;-------------------------Midi "hotkey" functions--------------------- 27 | space(note, vel) 28 | { 29 | if (vel) 30 | Send {Space down} 31 | else 32 | Send {Space up} 33 | } 34 | 35 | note60(note, vel) 36 | { 37 | if (vel) 38 | Send {Left down} 39 | else 40 | Send {Left up} 41 | } 42 | note62(note, vel) 43 | { 44 | if (vel) 45 | Send {Down down} 46 | else 47 | Send {Down up} 48 | } 49 | note63(note, vel) 50 | { 51 | if (vel) 52 | Send {Up down} 53 | else 54 | Send {Up up} 55 | } 56 | note64(note, vel) 57 | { 58 | if (vel) 59 | Send {Right down} 60 | else 61 | Send {Right up} 62 | } 63 | 64 | ;------------------------- Midi input library ---------------------- 65 | #include midi_in_lib.ahk --------------------------------------------------------------------------------