#include #include #include Opt("MustDeclareVars", 1) Opt("GUIOnEventMode", 1) Global $hGui = GUICreate("Midi In Example", 1000, 420) GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit") Global $cCombo = GUICtrlCreateCombo("", 10, 10, 400, 20) Global $cButton_Start = GUICtrlCreateButton("Start", 420, 10, 80, 20) GUICtrlSetOnEvent(-1, "_Midi_Start") Global $cButton_Stop = GUICtrlCreateButton("Stop", 510, 10, 80, 20) GUICtrlSetOnEvent(-1, "_Midi_Stop") GUICtrlCreateLabel("MIM_DATA", 10, 40, 100, 20) Global $cEdit_Data = GUICtrlCreateEdit("", 10, 60, 485, 350) GUICtrlCreateLabel("MIM_LONGDATA", 505, 40, 100, 20) Global $cEdit_LongData = GUICtrlCreateEdit("", 505, 60, 485, 350) GUISetState() _Midi_Startup() Global $tBuffer1 = _CreateBuffer() Global $tBuffer2 = _CreateBuffer() _GetDevices() Global $hMidi = 0 Global $bRelease = False Global $iDeviceCurrent = -1 GUIRegisterMsg($MM_MIM_CLOSE, "_MidiWinProc") GUIRegisterMsg($MM_MIM_DATA, "_MidiWinProc") GUIRegisterMsg($MM_MIM_ERROR, "_MidiWinProc") GUIRegisterMsg($MM_MIM_LONGDATA, "_MidiWinProc") GUIRegisterMsg($MM_MIM_LONGERROR, "_MidiWinProc") GUIRegisterMsg($MM_MIM_MOREDATA, "_MidiWinProc") GUIRegisterMsg($MM_MIM_OPEN, "_MidiWinProc") While Sleep(100) WEnd Func _ProcessLongData($pData, $iBytes) Local $tGetData = DllStructCreate("byte[" & $iBytes & "];", $pData) GUICtrlSetData($cEdit_LongData, DllStructGetData($tGetData, 1) & @CRLF, 1) EndFunc ;==>_ProcessLongData Func _ProcessData($iMidiMessage) Local $iLoWord = _WinAPI_LoWord($iMidiMessage) Local $iHiWord = _WinAPI_HiWord($iMidiMessage) Local $bStatus = BitAND($iLoWord, 0xFF) ;LoByte Local $bData1 = BitShift($iLoWord, 8) ;HiByte Local $bData2 = BitAND($iHiWord, 0xFF) ;LoByte Local $Chan = BitAND($bStatus, 0xF) Local $MidiMsg = BitShift($bStatus, 4) GUICtrlSetData($cEdit_Data, "StatusByte: " & $bStatus & @TAB & "DataByte1: " & $bData1 & @TAB & "DataByte2: " & $bData2 & @CRLF, 1) Switch $MidiMsg Case 0x8 ; Note Off GUICtrlSetData($cEdit_Data, @TAB & "NoteOff: MidiChannel: " & $Chan & @TAB & "NoteNumber: " & $bData1 & @TAB & "Velocity: " & $bData2 & @CRLF, 1) Case 0x9 ; Note On GUICtrlSetData($cEdit_Data, @TAB & "NoteOn: MidiChannel: " & $Chan & @TAB & "NoteNumber: " & $bData1 & @TAB & "Velocity: " & $bData2 & @CRLF, 1) Case 0xA ; Polyphonic aftertouch GUICtrlSetData($cEdit_Data, @TAB & "Polyphonic aftertouch: MidiChannel: " & $Chan & @TAB & "NoteNumber: " & $bData1 & @TAB & "Poly Pressure: " & $bData2 & @CRLF, 1) Case 0xB ; Control Change GUICtrlSetData($cEdit_Data, @TAB & "Control Change: MidiChannel: " & $Chan & @TAB & "Controller: " & $bData1 & @TAB & "Value: " & $bData2 & @CRLF, 1) Case 0xC ; Program Change GUICtrlSetData($cEdit_Data, @TAB & "Program Change: MidiChannel: " & $Chan & @TAB & "Programm: " & $bData1 & @CRLF, 1) Case 0xD ; Channel aftertouch GUICtrlSetData($cEdit_Data, @TAB & "Channel aftertouch: MidiChannel: " & $Chan & @TAB & "Aftertouch : " & $bData1 & @CRLF, 1) Case 0xE ; Pitch Bend GUICtrlSetData($cEdit_Data, @TAB & "Pitch Bend: MidiChannel: " & $Chan & @TAB & "LSB: " & $bData1 & @TAB & "MSB: " & $bData2 & @CRLF, 1) EndSwitch EndFunc ;==>_ProcessData Func _MidiWinProc($hWnd, $iMsg, $wParam, $lParam) Switch $iMsg Case $MIM_OPEN ConsoleWrite("> MIM_OPEN" & @CRLF) Case $MIM_CLOSE ;hMidi Handle ab jetzt ungültig ConsoleWrite("> MIM_CLOSE" & @CRLF) $hMidi = 0 Case $MIM_DATA ; Normale Midi MSG ConsoleWrite("> MIM_DATA" & @CRLF) _ProcessData($lParam) Case $MIM_MOREDATA ConsoleWrite("> MIM_MOREDATA" & @CRLF) Case $MIM_LONGDATA ConsoleWrite("> MIM_LONGDATA" & @CRLF) Switch $bRelease Case False ; SysEx Daten kommen rein Local $tMidiHDR = DllStructCreate($MIDIHDR, $lParam) Local $iBytesRecorded = DllStructGetData($tMidiHDR, "dwBytesRecorded") ConsoleWrite("+ LONGDATA IN: " & $iBytesRecorded & " bytes" & @CRLF) _ProcessLongData(DllStructGetData($tMidiHDR, "lpData"), $iBytesRecorded) _MidiIn_AddBuffer($hMidi, $lParam, 48) Case Else ; Druch _MidiIn_Reset wird hier der Buffer zurückgegeben und muss hier "unprepared" werden ConsoleWrite("! Unprepare Buffer" & @CRLF) _MidiIn_UnprepareHeader($hMidi, $lParam, 48) EndSwitch Case $MIM_ERROR ConsoleWrite("> MIM_ERROR" & @CRLF) Case $MIM_LONGERROR ConsoleWrite("> MIM_LONGERROR" & @CRLF) _MidiIn_AddBuffer($hMidi, $lParam, 48) EndSwitch EndFunc ;==>_MidiWinProc Func _Midi_Start() ConsoleWrite(@CRLF & "!=============================" & @CRLF) ConsoleWrite("! starting..." & @CRLF & @CRLF) Local $aRegExp = StringRegExp(GUICtrlRead($cCombo), "<(\d+)>", 3) If @error Or Not IsArray($aRegExp) Then Return Local $iDevice = $aRegExp[0] If $iDevice = $iDeviceCurrent Then ConsoleWrite("- already running" & @CRLF) Return EndIf $bRelease = False Local $iRet If $hMidi <> 0 Then _Midi_Stop() $hMidi = _MidiIn_Open($iDevice, $hGui, 0, BitOR($CALLBACK_WINDOW, $MIDI_IO_STATUS)) ConsoleWrite("! MidiIn Open: " & $hMidi & " error: " & @error & @CRLF) $iDeviceCurrent = $iDevice $iRet = _MidiIn_PrepareHeader($hMidi, DllStructGetPtr($tBuffer1, "lpData"), 48) ConsoleWrite("! Prepare Header: " & $iRet & " error: " & @error & @CRLF) $iRet = _MidiIn_PrepareHeader($hMidi, DllStructGetPtr($tBuffer2, "lpData"), 48) ConsoleWrite("! Prepare Header: " & $iRet & " error: " & @error & @CRLF) $iRet = _MidiIn_AddBuffer($hMidi, DllStructGetPtr($tBuffer2, "lpData"), 48) ConsoleWrite("! Add Buffer: " & $iRet & " error: " & @error & @CRLF) $iRet = _MidiIn_AddBuffer($hMidi, DllStructGetPtr($tBuffer1, "lpData"), 48) ConsoleWrite("! Add Buffer: " & $iRet & " error: " & @error & @CRLF) $iRet = _MidiIn_Start($hMidi) ConsoleWrite("! MidiIn Start: " & $iRet & " error: " & @error & @CRLF) EndFunc ;==>_Midi_Start Func _Midi_Stop() ConsoleWrite(@CRLF & "!=============================" & @CRLF) ConsoleWrite("! stopping..." & @CRLF & @CRLF) $bRelease = True Local $iRet $iRet = _MidiIn_Reset($hMidi) ConsoleWrite("! MidiIn Reset: " & $iRet & " error: " & @error & @CRLF) $iRet = _MidiIn_Stop($hMidi) ConsoleWrite("! MidiIn Stop: " & $iRet & " error: " & @error & @CRLF) $iRet = _MidiIn_Close($hMidi) ConsoleWrite("! MidiIn Close: " & $iRet & " error: " & @error & @CRLF) $iDeviceCurrent = -1 EndFunc ;==>_Midi_Stop Func _GetDevices() Local $tMidiInCaps = DllStructCreate($MIDIINCAPS) Local $pMidiInCaps = DllStructGetPtr($tMidiInCaps) Local $iMidiInCaps = DllStructGetSize($tMidiInCaps) Local $iDeviceCnt = _MidiIn_GetNumDevs() Local $sDevice = "" Local $sDefault = "" For $i = 0 To ($iDeviceCnt - 1) _MidiIn_GetDevCaps($i, $pMidiInCaps, $iMidiInCaps) $sDevice &= "<" & $i & "> " & DllStructGetData($tMidiInCaps, "szPname") & "|" If $i = 0 Then $sDefault = "<" & $i & "> " & DllStructGetData($tMidiInCaps, "szPname") Next GUICtrlSetData($cCombo, $sDevice, $sDefault) EndFunc ;==>_GetDevices Func _CreateBuffer($iSize = 256, $iID = 0) Local $tBuffer = DllStructCreate("uint BufferSize; byte BufferData[" & $iSize & "];" & $MIDIHDR) DllStructSetData($tBuffer, "BufferSize", $iSize) DllStructSetData($tBuffer, "lpData", DllStructGetPtr($tBuffer, "BufferData")) DllStructSetData($tBuffer, "dwBufferLength", $iSize) DllStructSetData($tBuffer, "dwUser", $iID) Return $tBuffer EndFunc ;==>_CreateBuffer Func _Exit() Exit EndFunc ;==>_Exit