Thank you so much for making this module!
I have been trying to solve a problem with multiple midi inputs.
Unable to solve my problem one way, I have look for alternative.
I found this module. Since all I really need is data values coming back to the main script, I thought this module made sense.
I am trying to send the midi note number from script1 to script2.
Script2.ahk as well as IPC.ahk (from module archive) remain untouched and script2 is running. Once it gets to script2 I will do other stuff with the note number, like trigger keystrokes.
I confirm the following -
1. Edited Script1.ahk successfully sends the edit box to script 2.
2. Midi input is working and midi messages are being split up into bytes.
3. Midi note numbers are correct and show up in script1 gui box.
Can someone please take a look and help me route my data properly?
Script1.ahk edited as follows including the midi input.
Code:
;#SingleInstance, off ;allow multiple instances
target := "Script2"
stress := 1000, x:=300
;========================
Gui, +LastFound +AlwaysOnTop
hScript := WinExist() + 0
Gui, Font, s10
Gui, Add, Edit, vMyMsg w200 , midiMsg
Gui, Add, Edit, x+0 vMyPort w50, 100
Gui, Font, s8
Gui, Add, Button, x+5 gOnSend , Send
Gui, Add, Button, x+5 gOnSendBinary , Send Binary
Gui, Add, Button, x+5 gOnStress , Stress
Gui, Add, ListBox,xm w440 h300 vMyLB,
Gui, Show, x%x% AutoSize
GuiControl, , MyLB, This script HWND: %hScript%
IPC_SetHandler("OnData")
; -------- inserted code ----------
/*
I am trying to get the midi note number input passed to script 2.
I currently have it showing the note number pressed in this scripts window
Script1.
*/
; SET THIS DEVICEiD TO YOUR MIDI INPUT PORT, 0 IS THE FIRST MIDI PORT,
; most of this code written by orbik.
DeviceID := 1 ; hardware keyboard
CALLBACK_WINDOW := 0x10000
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#Persistent
Gui, +LastFound
hWnd := WinExist()
OpenCloseMidiAPI()
OnExit, Sub_Exit
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
result := DllCall("winmm.dll\midiInStart", UInt,hMidiIn)
If result
{
MsgBox, error, midiInStart returned %result%`n
GoSub, sub_exit
}
; for reference only
; #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") ; calling the function below
OnMessage(0x3C2, "midiInHandler")
OnMessage(0x3C3, "midiInHandler")
OnMessage(0x3C4, "midiInHandler")
OnMessage(0x3C5, "midiInHandler")
OnMessage(0x3C6, "midiInHandler")
return
;--------End of auto-execute section-----
OpenCloseMidiAPI() ; calls the winmm.dll to close midi port
{
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) ; THIS IS THE MIDI IN FUNCTION WHERE THE MIDI MESSAGE IS BROKEN UP
{
statusbyte := midiMsg & 0xFF ; EXTRACT THE STATUS BYTE (WHAT KIND OF MIDI MESSAGE IS IT)
chan := (statusbyte & 0x0f) + 1 ; WHAT MIDI CHANNEL IS THE MESSAGE ON?
byte1 := (midiMsg >> 8) & 0xFF ; THIS IS DATA1 VALUE = NOTE NUMBER OR CC NUMBER
byte2 := (midiMsg >> 16) & 0xFF ; DATA2 VALUE IS NOTE VELEOCITY OR CC VALUE
IfEqual, statusbyte, 144 ; test for noteOn message
{
; how do I get byte1 "note number" sent to script2?
Data := byte1 ; set var to the byte1 Midi note number
OnData(Hwnd, Data, Port, Size)
;IPC_Send( WinExist( target ), %byte1%, MyPort)
;gosub, OnSend
}
Else
{
}
}
;------ end of inserted code ---
return
OnData(Hwnd, Data, Port, Size)
{
global myLB
if Size =
s = %Port% Hwnd: %hwnd% Message: %Data%
else
{
x := NumGet(Data+0), y := NumGet(Data+4)
s = %Port% Hwnd: %HWND% Binary Data: POINT (%x%, %y%) DataSize: %Size%
}
GuiControl, , MyLB, %s%
}
OnSend:
Gui, Submit, NoHide
if !IPC_Send( WinExist( target ), MyMsg, MyPort)
MsgBox Sending failed
return
OnStress:
Gui, Submit, NoHide
if !(h := WinExist( target ))
MsgBox Host doesn't exist
loop, %stress%
IPC_Send(h, MyMsg " : " A_Index, MyPort)
return
OnSendBinary:
Gui, Submit, NoHide
VarSetCapacity(POINT, 8), NumPut(2000, POINT), NumPut(8000, POINT, 4)
if !IPC_Send( WinExist( target ), &POINT, MyPort, 8)
MsgBox Sending failed
return
GuiClose:
ExitApp
return
; =============== this will exit the app when esc is pushed
Esc::GoSub, sub_exit
sub_exit:
If (hMidiIn)
DllCall("winmm.dll\midiInClose", UInt,hMidiIn)
OpenCloseMidiAPI()
ExitApp
#include ..\IPC.ahk
Thank you for looking!