@ 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
но BANG !!!в конце концов это происходит ...
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.
Скажите, пожалуйста, почему?