这通常是关于接收多个MIDI系统专有消息,但特别是配备MIDI的套件是Fender Cyber Twin(CT)吉他放大器。
注意:SYSEX =系统专有
我知道是否从我的应用发送了此MIDI单个预设转储请求:
{ F0, 08, 21, 11, 04, 22, 00, 00, 00, 02, 7B, F7 }
根据我的MIDI_OX应用程序,将CT很好地发送给CT或我从CT手动转储,CT会很好地发送以下SYSEX消息:
TIMESTAMP IN PORT STATUS DATA1 DATA2 CHAN NOTE EVENT
00003A9A 1 2 F0 Buffer: 6 Bytes System Exclusive
SYSX: F0 08 21 11 02 F7
00003B7F 1 2 F0 Buffer: 55 Bytes System Exclusive
SYSX: F0 08 21 11 02 00 00 38 00 56 69 62 72 6F 2D 50 00 61
SYSX: 67 65 20 20 20 20 07 20 20 08 5A 61 68 70 1D 4F 50 6E
SYSX: 24 10 79 14 1C 00 77 26 0D 54 69 64 40 5D 3C 4D 7F 4F
SYSX: F7
00003BDC 1 2 F0 Buffer: 7 Bytes System Exclusive
SYSX: F0 08 21 11 02 7B F7
即 3 {F0 ... F7} SYSEX数据包。
当我从Button发送MIDI单个预设转储请求时,我仅收到第一个{F0 08 21 11 02 F7},即单个预设(6个字节)的CT转储文件开始包。
如何获取其他2个数据包。第二个是文件本身(55个字节)和CT转储文件结束包(7个字节)
为清楚起见,这是关于接收多个SYSEX消息,而不涉及CT ,这恰好是我连接的工具包。
还有另一种询问方式:
无论是作为对我的应用程序的响应(即预期收到多个SYSEX消息)还是外部响应(即不知道预期的内容或时间),我如何始终保持SYSEX接收状态 < / p>
我肯定会丢失一些东西!
我的控制台显示:
yaaay found MIDI Plus In @ 0
yaaay found MIDI Plus @ 1
hello
response: 0, hMIDIout: 13573704
size of requestdump: 12
Hello from MIDIin
MIM_OPEN
response midiInOpen: 0, hMIDIin: 13572912
response midiInPrepareHeader: 0, hMIDIin: 13572912
response midiInAddBuffer: 0, hMIDIin: 13572912
response : 0, hMIDIin: 13572912
sizes: 48
size of requestdump: 12
response: 0
response: 0
response: 0
sent:
F0, 08, 21, 11, 04, 22, 00, 00, 00, 02, 7B, F7
MIM_LONGDATA: wParam = 0x02C8CF10
bytes recorded: 6
F0, 08, 21, 11, 02, F7
flags: 0x0003
next: 0x0000
没有MIDI错误,只有单个预设(6个字节)的CT转储文件开始包!
这些是我的 MIDI IN 和 MIDI OUT 类以及 Form 和 MIDIglobals 模块: 该表单仅找到我需要的MIDI输入/输出设备,根据它们的设备ID创建新的MIDIin和MIDIout实例,并具有一个按钮,用于从我的CT启动单个预设转储。
MIDI IN
Imports System.Runtime.InteropServices
Public Class MIDIin
Dim sysexbufffer(8192) As Byte
Dim hMIDIin As Integer
Dim MidiInHdr As New MIDIHDR
Dim n As Integer
Public Sub New(ByVal device As Integer)
Dim response As Integer
Console.Out.WriteLine("Hello from MIDIin")
response = midiInOpen(hMIDIin, device, AddressOf MidiCallback, 1, MIDI_CALLBACK_FUNCTION Or MIDI_IO_STATUS)
Console.Out.WriteLine("response midiInOpen: " & response & ", hMIDIin: " & hMIDIin)
MidiInHdr.dwBufferLength = sysexbufffer.Length
MidiInHdr.lpData = Marshal.AllocHGlobal(sysexbufffer.Length)
response = midiInPrepareHeader(hMIDIin, MidiInHdr, sysexbufffer.Length)
Console.Out.WriteLine("response midiInPrepareHeader: " & response & ", hMIDIin: " & hMIDIin)
response = midiInAddBuffer(hMIDIin, MidiInHdr, Marshal.SizeOf(MidiInHdr))
Console.Out.WriteLine("response midiInAddBuffer: " & response & ", hMIDIin: " & hMIDIin)
response = midiInStart(hMIDIin)
Console.Out.WriteLine("response : " & response & ", hMIDIin: " & hMIDIin)
End Sub
Sub MidiCallback(ByVal MidiHandle As Int32, ByVal wMsg As Int32, ByVal Instance As Int32, ByVal wParam As Int32, ByVal lParam As Int32)
'Dim g As String = "MidiCallBack(" & Hex4(wMsg) & ", " & Instance & ", " & Hex4(wParam) & ", " & Hex4(lParam) & ")"
'Console.Out.WriteLine("MidiCallBack vMsg: 0x" & Hex4(wMsg))
Select Case wMsg
Case MIM_OPEN
Console.Out.WriteLine("MIM_OPEN")
Case MIM_CLOSE
Console.Out.WriteLine("MIM_CLOSE")
Case MIM_DATA
Console.Out.WriteLine("MIM_DATA wParam: 0x" & Hex8(wParam))
Case MIM_LONGDATA
Console.Out.WriteLine("MIM_LONGDATA: wParam = 0x" & Hex8(wParam))
Console.Out.WriteLine("bytes recorded: " & MidiInHdr.dwBytesRecorded)
Dim i As Integer
Dim b As Byte
For i = 0 To MidiInHdr.dwBytesRecorded - 1
b = Marshal.ReadByte(MidiInHdr.lpData + i)
Console.Out.Write(Hex2(b) & IIf(i < MidiInHdr.dwBytesRecorded - 1, ", ", vbCrLf))
Next
Console.Out.WriteLine("flags: 0x" & Hex4(MidiInHdr.dwFlags))
Console.Out.WriteLine("next: 0x" & Hex4(MidiInHdr.lpNext))
Case Else
Console.Out.WriteLine("Not known: vMsg: 0x" & Hex8(wMsg))
End Select
n = n + 1
End Sub
Protected Overrides Sub Finalize()
midiInStop(hMIDIin)
midiInClose(hMIDIin)
Marshal.FreeHGlobal(MidiInHdr.lpData)
Console.Out.WriteLine("finalised MIDI In: " & hMIDIin)
End Sub
End Class
MIDI OUT
Imports System.Runtime.InteropServices
Class MIDIout
Dim requestdump As Byte() =
{cSEX, cFender, cAMP, cCYBERTWIN, cMESSAGEID, cDUMPREQUEST, cUNUSED, cUNUSED, cUNUSED, cDUMPID, cEOXFILE, cEOX}
Dim hMIDIout As Integer
Dim MidiOutHdr As New MIDIHDR
Public Sub New(ByVal device As Integer)
Dim response As Integer
Console.Out.WriteLine("hello")
response = midiOutOpen(hMIDIout, device, 0, 0, 0)
Console.Out.WriteLine("response: " & response & ", hMIDIout: " & hMIDIout)
Console.Out.WriteLine("size of requestdump: " & requestdump.Length)
End Sub
Private Sub dumpRequest(ByVal type As Integer)
requestdump(cDUMPIDBYTE) = type
If type < 1 Or type > 3 Then
Console.Out.WriteLine("bad request type: " & type)
Exit Sub
End If
Dim response As Integer
Console.Out.WriteLine("sizes: " & Marshal.SizeOf(MidiOutHdr))
Console.Out.WriteLine("size of requestdump: " & requestdump.Length)
MidiOutHdr.dwBufferLength = requestdump.Length
MidiOutHdr.lpData = Marshal.AllocHGlobal(requestdump.Length)
Marshal.Copy(requestdump, 0, MidiOutHdr.lpData, requestdump.Length)
response = midiOutPrepareHeader(hMIDIout, MidiOutHdr, Marshal.SizeOf(MidiOutHdr))
Console.Out.WriteLine("response: " & response)
response = midiOutLongMsg(hMIDIout, MidiOutHdr, Marshal.SizeOf(MidiOutHdr))
Console.Out.WriteLine("response: " & response)
response = midiOutUnprepareHeader(hMIDIout, MidiOutHdr, Marshal.SizeOf(MidiOutHdr))
Console.Out.WriteLine("response: " & response)
Marshal.FreeHGlobal(MidiOutHdr.lpData)
Dim i As Integer
Console.Out.WriteLine("sent: ")
For i = 0 To 11
Console.Out.Write(Hex2(requestdump(i)) & IIf(i = 11, vbCrLf, ", "))
Next
End Sub
Public Sub RequestUtilitiesDump()
dumpRequest(cUTILITIESDUMPID)
End Sub
Public Sub RequestSinglePresetDump()
dumpRequest(cSINGLEPRESETDUMPID)
End Sub
Public Sub RequestAllPresetsDump()
dumpRequest(cALLPRESETSDUMPID)
End Sub
Protected Overrides Sub Finalize()
midiOutClose(hMIDIout)
Console.Out.WriteLine("finalised MIDI out: " & hMIDIout)
End Sub
End Class
表格
Imports System.Runtime.InteropServices
Class Form1
Dim outdevice As Integer = -1
Dim indevice As Integer = -1
Dim mOut As MIDIout
Dim mIn As MIDIin
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim incaps As New MIDIINCAPS
Dim outcaps As New MIDIOUTCAPS
Dim NumberOfInDevices As Integer
Dim NumberOfOutDevices As Integer
Dim devicesought As String = "midi plus"
NumberOfInDevices = midiInGetNumDevs()
NumberOfOutDevices = midiOutGetNumDevs()
Dim device As Integer
For device = 0 To NumberOfInDevices - 1
midiInGetDevCaps(device, incaps, Marshal.SizeOf(incaps))
If incaps.szPname.ToLower.Equals(devicesought) Then
Console.Out.WriteLine("Found MIDI Plus In @ " & device)
indevice = device
End If
Next
For device = 0 To NumberOfOutDevices - 1
midiOutGetDevCaps(device, outcaps, Marshal.SizeOf(outcaps))
If outcaps.szPname.ToLower.Equals(devicesought) Then
Console.Out.WriteLine("yaaay found MIDI Plus @ " & device)
outdevice = device
End If
Next
mOut = New MIDIout(outdevice)
mIn = New MIDIin(indevice)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
mOut.RequestSinglePresetDump()
End Sub
End Class
MIDIglobals
Imports System.Runtime.InteropServices
Module MIDIglobals
Public Function Hex2(b As Byte) As String
Hex2 = Strings.Right("00" & Hex(b), 2)
End Function
Public Function HexInt2(i As Integer) As String
Dim b As Byte = (i And &HFF)
HexInt2 = Hex2(b)
End Function
Public Function Hex4(i As Integer) As String
Hex4 = Strings.Right("0000" & Hex(i), 4)
End Function
Public Function Hex8(i As Integer) As String
Hex8 = Strings.Right("00000000" & Hex(i), 8)
End Function
'for Cyber Twin
Public Const cSEX As Byte = &HF0
Public Const cEOX As Byte = &HF7
Public Const cFender As Byte = &H8
Public Const cAMP As Byte = &H21
Public Const cCYBERTWIN As Byte = &H11
Public Const cMESSAGEID As Byte = &H4
Public Const cDUMPREQUEST As Byte = &H22
Public Const cUNUSED As Byte = &H0
Public Const cDUMPID As Byte = &H0
Public Const cUTILITIESDUMPID As Byte = &H1
Public Const cSINGLEPRESETDUMPID As Byte = &H2
Public Const cALLPRESETSDUMPID As Byte = &H3
Public Const cEOXFILE As Byte = &H7B
Public Const cDUMPIDBYTE As Byte = 9
' MIDI input device capabilities structure
Public Structure MIDIINCAPS
Dim wMid As Short ' Manufacturer ID
Dim wPid As Short ' Product ID
Dim vDriverVersion As Integer ' Driver version
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> Dim szPname As String ' Product Name
Dim dwSupport As Integer ' Supported extras
End Structure
' MIDI output device capabilities structure
Public Structure MIDIOUTCAPS
Dim wMid As Short ' Manufacturer ID
Dim wPid As Short ' Product ID
Dim vDriverVersion As Integer ' Driver version
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> Dim szPname As String ' Product Name
Dim wTechnology As Short ' Device type
Dim wVoices As Short ' n. of voices (internal synth only)
Dim wNotes As Short ' max n. of notes (internal synth only)
Dim wChannelMask As Short ' n. of Midi channels (internal synth only)
Dim dwSupport As Integer ' Supported extra controllers (volume, etc)
End Structure
' MIDI data block header
Public Structure MIDIHDR
Dim lpData As IntPtr ' pointer to locked data block
Dim dwBufferLength As Integer ' length of data in data block
Dim dwBytesRecorded As Integer ' used for input only
Dim dwUser As Integer ' for client's use
Dim dwFlags As Integer ' assorted flags (see defines)
Dim lpNext As Integer ' reserved for driver
Dim reserved As Integer ' reserved for driver
Dim dwOffset As Integer
Dim reserved1 As Integer
Dim reserved2 As Integer
Dim reserved3 As Integer
Dim reserved4 As Integer
End Structure
'Input functions
Declare Function midiInGetNumDevs Lib "winmm.dll" () As Short
Declare Function midiInGetDevCaps Lib "winmm.dll" Alias "midiInGetDevCapsA" (ByVal uDeviceID As Integer, ByRef lpCaps As MIDIINCAPS, ByVal uSize As Integer) As Integer
Declare Function midiInGetErrorText Lib "winmm.dll" Alias "midiInGetErrorTextA" (ByVal err_Renamed As Integer, ByVal lpText As String, ByVal uSize As Integer) As Integer
Declare Function midiInOpen Lib "winmm.dll" (ByRef lphMidiIn As Integer, ByVal uDeviceID As Integer, ByVal dwCallback As MidiDelegate,
ByVal dwInstance As Integer, ByVal dwFlags As Integer) As Integer
Declare Function midiInClose Lib "winmm.dll" (ByVal hMidiIN As Integer) As Integer
Declare Function midiInPrepareHeader Lib "winmm.dll" (ByVal hMidiIN As Integer, ByRef lpMidiInHdr As MIDIHDR, ByVal uSize As Integer) As Integer
Declare Function midiInUnprepareHeader Lib "winmm.dll" (ByVal hMidiIN As Integer, ByRef lpMidiInHdr As MIDIHDR, ByVal uSize As Integer) As Integer
Declare Function midiInAddBuffer Lib "winmm.dll" (ByVal hMidiIN As Integer, ByRef lpMidiInHdr As MIDIHDR, ByVal uSize As Integer) As Integer
Declare Function midiInReset Lib "winmm.dll" (ByVal hMidiIN As Integer) As Integer
Declare Function midiInStart Lib "winmm.dll" (ByVal hMidiIN As Integer) As Integer
Declare Function midiInStop Lib "winmm.dll" (ByVal hMidiIN As Integer) As Integer
'Output functions
Declare Function midiOutGetNumDevs Lib "winmm.dll" () As Short
Declare Function midiOutGetDevCaps Lib "winmm.dll" Alias "midiOutGetDevCapsA" (ByVal uDeviceID As Integer, ByRef lpCaps As MIDIOUTCAPS, ByVal uSize As Integer) As Integer
Declare Function midiOutGetErrorText Lib "winmm.dll" Alias "midiOutGetErrorTextA" (ByVal errcode As Integer, ByVal lpText As String, ByVal uSize As Integer) As Integer
Declare Function midiOutOpen Lib "winmm.dll" (ByRef lphMidiOut As Integer, ByVal uDeviceID As Integer, ByVal dwCallback As Integer,
ByVal dwInstance As Integer, ByVal dwFlags As Integer) As Integer
Declare Function midiOutClose Lib "winmm.dll" (ByVal hMidiOut As Integer) As Integer
Declare Function midiOutPrepareHeader Lib "winmm.dll" (ByVal hMidiOut As Integer, ByRef lpMidiOutHdr As MIDIHDR, ByVal uSize As Integer) As Integer
Declare Function midiOutUnprepareHeader Lib "winmm.dll" (ByVal hMidiOut As Integer, ByRef lpMidiOutHdr As MIDIHDR, ByVal uSize As Integer) As Integer
Declare Function midiOutShortMsg Lib "winmm.dll" (ByVal hMidiOut As Integer, ByVal dwMsg As Integer) As Integer
Declare Function midiOutLongMsg Lib "winmm.dll" (ByVal hMidiOut As Integer, ByRef lpMidiOutHdr As MIDIHDR, ByVal uSize As Integer) As Integer
Public Delegate Sub MidiDelegate(ByVal MidiHandle As Int32, ByVal wMsg As Int32, ByVal Instance As Int32, ByVal wParam As Int32, ByVal lParam As Int32)
' Callback Function constants
Public Const MIDI_CALLBACK_FUNCTION As Integer = &H30000 ' dwCallback is a FARPROC
Public Const MIDI_IO_STATUS As Integer = &H20 ' include longdata and moredata
Public Const MIM_OPEN As Short = &H3C1S ' MIDI In Port Opened
Public Const MIM_CLOSE As Short = &H3C2S ' MIDI In Port Closed
Public Const MIM_DATA As Short = &H3C3S ' MIDI In Short Data (e.g. Notes & CC)
Public Const MIM_LONGDATA As Short = &H3C4S ' MIDI In Long Data (i.e. SYSEX)
Public Const MIM_MOREDATA As Short = &H3CCS ' MIDI In More Data overflow of non sys ex data
Public Const MIM_ERROR As Short = &H3C5S ' MIDI In Error
Public Const MIM_LONGERROR As Short = &H3C6S ' MIDI In Long Error
Public Const MOM_OPEN As Short = &H3C7S ' MIDI Out Port Opened
Public Const MOM_CLOSE As Short = &H3C8S ' MIDI Out Port Closed
Public Const MOM_DONE As Short = &H3C9S ' MIDI Out Data sending completed
Public Const MOM_POSITIONCB As Short = &HCAS ' MIDI Out Position requested
' Midi Error Constants
Public Const MMSYSERR_NOERROR As Short = 0
Public Const MMSYSERR_ERROR As Short = 1
Public Const MMSYSERR_BADDEVICEID As Short = 2
Public Const MMSYSERR_NOTENABLED As Short = 3
Public Const MMSYSERR_ALLOCATED As Short = 4
Public Const MMSYSERR_INVALHANDLE As Short = 5
Public Const MMSYSERR_NODRIVER As Short = 6
Public Const MMSYSERR_NOMEM As Short = 7
Public Const MMSYSERR_NOTSUPPORTED As Short = 8
Public Const MMSYSERR_BADERRNUM As Short = 9
Public Const MMSYSERR_INVALFLAG As Short = 10
Public Const MMSYSERR_INVALPARAM As Short = 11
Public Const MMSYSERR_HANDLEBUSY As Short = 12
Public Const MMSYSERR_INVALIDALIAS As Short = 13
Public Const MMSYSERR_BADDB As Short = 14
Public Const MMSYSERR_KEYNOTFOUND As Short = 15
Public Const MMSYSERR_READERROR As Short = 16
Public Const MMSYSERR_WRITEERROR As Short = 17
Public Const MMSYSERR_DELETEERROR As Short = 18
Public Const MMSYSERR_VALNOTFOUND As Short = 19
Public Const MMSYSERR_NODRIVERCB As Short = 20
Public Const MMSYSERR_LASTERROR As Short = 20
Public Const MIDIERR_UNPREPARED As Short = 64 ' header not prepared
Public Const MIDIERR_STILLPLAYING As Short = 65 ' still something playing
Public Const MIDIERR_NOMAP As Short = 66 ' no current map
Public Const MIDIERR_NOTREADY As Short = 67 ' hardware is still busy
Public Const MIDIERR_NODEVICE As Short = 68 ' port no longer connected
Public Const MIDIERR_INVALIDSETUP As Short = 69 ' invalid setup
Public Const MIDIERR_LASTERROR As Short = 69 ' last error in range
' Midi Header flags
Public Const MHDR_DONE As Short = 1 ' Set by the device driver to indicate that it is finished with the buffer and is returning it to the application.
Public Const MHDR_PREPARED As Short = 2 ' Set by Windows to indicate that the buffer has been prepared
Public Const MHDR_INQUEUE As Short = 4 ' Set by Windows to indicate that the buffer is queued for playback
Public Const MHDR_ISSTRM As Short = 8 ' Set to indicate that the buffer is a stream buffer
End Module
答案 0 :(得分:2)
您的回调处理完缓冲区中的数据后,应使用midiInAddBuffer
重新提交。
要处理一次到达的多个消息,您应该有多个缓冲区。
在关闭设备之前,您必须先reset the device to return all pending buffers和clean up the buffers。
答案 1 :(得分:0)
@CL。谢谢。我事实上,我一直在朝着这个方向努力。 我的 MIDIin 类现在看起来像:
Imports System.Runtime.InteropServices
Public Class MIDIin
Const SYSEXbufferSize = 64
Const NumSysExHeaders = 10
Dim hMIDIin As Integer
Dim MidiInHdr(NumSysExHeaders) As MIDIHDR
Dim n As Integer
Dim mhdr As New MIDIHDR
Public Sub New(ByVal device As Integer
Dim response As Integer, i As Integer
Console.Out.WriteLine("Hello from MIDIin")
response = midiInOpen(hMIDIin, device, AddressOf MidiCallback, 1, MIDI_CALLBACK_FUNCTION Or MIDI_IO_STATUS)
Console.Out.WriteLine("response midiInOpen: " & response & ", hMIDIin: " & hMIDIin)
Dim size As Integer = Marshal.SizeOf(mhdr)
For i = 0 To NumSysExHeaders - 1
MidiInHdr(i) = New MIDIHDR
MidiInHdr(i).dwBufferLength = SYSEXbufferSize
' save the array index in the dwUser member for later use
MidiInHdr(i).dwUser = i
MidiInHdr(i).lpData = Marshal.AllocHGlobal(SYSEXbufferSize)
response = midiInPrepareHeader(hMIDIin, MidiInHdr(i), size)
Console.Out.WriteLine("??: " & MidiInHdr(i).lpData.ToString)
response = midiInAddBuffer(hMIDIin, MidiInHdr(i), size)
'Console.Out.WriteLine("response midiInAddBuffer: " & response & ", hMIDIin: " & hMIDIin)
Next
response = midiInStart(hMIDIin)
Console.Out.WriteLine("response : " & response & ", hMIDIin: " & hMIDIin)
End Sub
Sub MidiCallback(ByVal MidiHandle As Int32, ByVal wMsg As Int32, ByVal Instance As Int32, ByVal wParam As Int32, ByVal lParam As Int32)
'Dim g As String = "MidiCallBack(" & Hex4(wMsg) & ", " & Instance & ", " & Hex4(wParam) & ", " & Hex4(lParam) & ")"
'Console.Out.WriteLine("MidiCallBack vMsg: 0x" & Hex4(wMsg))
Select Case wMsg
Case MIM_OPEN
Console.Out.WriteLine("MIM_OPEN")
Case MIM_CLOSE
Console.Out.WriteLine("MIM_CLOSE")
Case MIM_DATA
Console.Out.WriteLine("MIM_DATA wParam: 0x" & Hex8(wParam))
Case MIM_LONGDATA
Console.Out.WriteLine("MIM_LONGDATA: wParam = 0x" & Hex8(wParam))
' I haven't the frst clue of how to change wParam into a pointerto a MIDIHDR structure
'so get Get the index of my arrays of MIDIHDRs from the dwUser member
'by using Marshal
Dim mhdrIndex = Marshal.ReadInt32(wParam + 12)
Console.Out.WriteLine("mhdrIndex: " & mhdrIndex)
Dim count As Integer = 0
Dim b As Byte
For i = 0 To MidiInHdr(mhdrIndex).dwBytesRecorded - 1
b = Marshal.ReadByte(MidiInHdr(mhdrIndex).lpData + i)
Console.Out.Write(Hex2(b))
count = count + 1
If count > 7 Or i = MidiInHdr(mhdrIndex).dwBytesRecorded - 1 Then
Console.Out.Write(vbCrLf)
count = 0
Else
Console.Out.Write(", ")
End If
Next
If MidiInHdr(mhdrIndex).dwFlags And MHDR_DONE <> 0 Then
' tidy up just incase. it makes no difference anyway
midiInUnprepareHeader(hMIDIin, MidiInHdr(mhdrIndex), Marshal.SizeOf(MidiInHdr(mhdrIndex)))
MidiInHdr(mhdrIndex).dwUser = mhdrIndex
midiInPrepareHeader(hMIDIin, MidiInHdr(mhdrIndex), Marshal.SizeOf(MidiInHdr(mhdrIndex)))
' add the buffer back
midiInAddBuffer(hMIDIin, MidiInHdr(mhdrIndex), Marshal.SizeOf(MidiInHdr(mhdrIndex)))
End If
Case Else
'display the rest of messages generically
Console.Out.WriteLine("Not known: vMsg: 0x" & Hex8(wMsg))
'Case MM_MOREDATA
End Select
n = n + 1
End Sub
Protected Overrides Sub Finalize()
Dim i As Integer
midiInStop(hMIDIin)
midiInClose(hMIDIin)
For i = 0 To MidiInHdr.Length - 1
Marshal.FreeHGlobal(MidiInHdr(i).lpData)
Next
Console.Out.WriteLine("finalised MIDI In: " & hMIDIin)
End Sub
End Class
在发送转储时,所有预设请求均通过以下方式发送:
F0, 08, 21, 11, 04, 22, 00, 00, 00, 03, 7B, F7
我现在看到所有补丁:
hello
response: 0, hMIDIout: 14321304
size of requestdump: 12
Hello from MIDIin
MIM_OPEN
response midiInOpen: 0, hMIDIin: 14318840
??: 14650696
??: 14650264
??: 14651488
??: 14651560
??: 14651632
??: 14650336
??: 14649112
??: 14648032
??: 14647816
??: 14648536
response : 0, hMIDIin: 14318840
sizes: 48
size of requestdump: 12
response: 0
response: 0
response: 0
sent:
F0, 08, 21, 11, 04, 22, 00, 00, 00, 03, 7B, F7
MIM_LONGDATA: wParam = 0x02B3D014
mhdrIndex: 0
F0, 08, 21, 11, 03, F7 ' start of file marker
MIM_LONGDATA: wParam = 0x02B3D044
mhdrIndex: 1
F0, 08, 21, 11, 03, 00, 00, 55
00, 43, 68, 61, 6D, 70, 20, 27
00, 34, 39, 20, 20, 20, 20, 20
05, 20, 20, 24, 0C, 40, 44, 51
0B, 40, 7F, 7C, 48, 28, 73, 68
00, 00, 00, 7F, 7F, 7F, 7F, 00
00, 00, 00, 00, 00, 58, F7
MIM_LONGDATA: wParam = 0x02B3D074
mhdrIndex: 2
F0, 08, 21, 11, 03, 01, 00, 56
00, 43, 68, 61, 6D, 70, 20, 27
00, 34, 39, 20, 20, 20, 20, 20
05, 20, 20, 24, 0C, 40, 42, 51
0B, 40, 7F, 7C, 48, 28, 73, 68
00, 00, 00, 7F, 7F, 7F, 7F, 00
00, 00, 00, 00, 00, 5C, F7
MIM_LONGDATA: wParam = 0x02B3D0A4
mhdrIndex: 3
F0, 08, 21, 11, 03, 02, 00, 57
00, 41, 20, 54, 77, 69, 6E, 20
00, 52, 65, 76, 65, 72, 62, 20
0D, 20, 20, 1C, 09, 42, 08, 52
1D, 4C, 72, 02, 16, 3C, 52, 1A
73, 7F, 04, 45, 59, 7F, 59, 60
48, 05, 31, 3D, 05, 4A, F7
MIM_LONGDATA: wParam = 0x02B3D0D4
mhdrIndex: 4
F0, 08, 21, 11, 03, 03, 00, 58
00, 43, 6F, 75, 6E, 74, 72, 79
00, 20, 54, 77, 61, 6E, 67, 65
0D, 72, 20, 04, 01, 40, 18, 50
15, 44, 2E, 3C, 75, 79, 5C, 74
1F, 32, 7A, 56, 48, 18, 5D, 1E
18, 41, 7F, 57, 7F, 0F, F7
MIM_LONGDATA: wParam = 0x02B3D104
mhdrIndex: 5
F0, 08, 21, 11, 03, 04, 00, 59
00, 4A, 61, 7A, 7A, 20, 49, 49
00, 20, 20, 20, 20, 20, 20, 20
0D, 20, 20, 1C, 31, 40, 08, 55
3A, 40, 0D, 15, 14, 6E, 44, 5D
1C, 04, 0F, 63, 71, 3E, 52, 4A
18, 4B, 7D, 46, 7C, 46, F7
一直到:
mhdrIndex: 4
F0, 08, 21, 11, 03, 4B, 01, 4B
00, 56, 69, 6E, 74, 61, 67, 65
00, 20, 53, 74, 61, 63, 6B, 20
0D, 20, 20, 10, 66, 40, 58, 51
3B, 40, 7E, 4F, 48, 20, 65, 6D
00, 1B, 00, 7F, 7F, 7F, 7F, 00
00, 00, 00, 00, 00, 31, F7
MIM_LONGDATA: wParam = 0x02B3D104
mhdrIndex: 5
F0, 08, 21, 11, 03, 4C, 01, 4C
00, 4D, 6F, 64, 65, 72, 6E, 20
00, 53, 74, 61, 63, 6B, 20, 20
0D, 20, 20, 45, 6E, 40, 58, 50
3F, 40, 0F, 06, 7A, 03, 36, 1C
40, 22, 7C, 7F, 7F, 7F, 7F, 00
00, 00, 00, 00, 00, 3E, F7
MIM_LONGDATA: wParam = 0x02B3D134
mhdrIndex: 6
F0, 08, 21, 11, 03, 7B, F7 end of file marker
但是砰!!!最终这会发生...
CallbackOnCollectedDelegate occurred Message:
Managed Debugging Assistant 'CallbackOnCollectedDelegate'
has detected a problem in
'C:\Visual Studio Projects\VisualBasic\MIDISysEx\MIDISysEx\
bin\Debug\MIDISysEx.vshost.exe'.
Additional information: A callback was made on a garbage
collected delegate of type
'MIDISysEx!MIDISysEx.MIDIglobals+MidiDelegate::Invoke'.
This may cause application crashes, corruption and data loss.
When passing delegates to unmanaged code, they must be kept
alive by the managed application until it is guaranteed that
they will never be called.
无论是接收转储数据作为对应用程序的响应还是从MIDI放大器手动接收,都会发生。
你能告诉我为什么吗?