Hi Leute!
Programmiere mit VB.NET unter WIn XP SP2
Und wieder treibt mich die Win-API benutzung in den Wahnsinn!!!
Folgende Strukturen habe ich vom API Viewer übernommen:
<StructLayout(LayoutKind.Sequential)> Structure MIDIHDR
Public lpData As Int32
Public dwBufferLength As Int32
Public dwBytesRecorded As Int32
Public dwUser As Int32
Public dwFlags As Int32
Public lpNext As Int32
Public Reserved As Int32
End Structure
<StructLayout(LayoutKind.Sequential)> _
Structure MIDIEVENT
Public dwDeltaTime As Int32 ' Ticks since last event
Public dwStreamID As Int32 ' Reserved - must be zero
Public dwEvent As Int32 ' Event type and parameters
Public dwParms() As Int32 ' Parameters if this is a long event
End Structure Ich möchte einen MidiStream an meinen Port senden und muss sicherstellen, dass die Daten genau zur richtigen Zeit gesendet werden (ein sequencer soll gesteuert werden).
Ich glaube das funktioniert nur mit der Funktion Midistreamout() in Verbindung mit midioutprepareheader(), oder?
also:
Declare Function midiStreamOpen Lib "winmm.dll" ( _
ByRef phms As Int32, _
ByRef puDeviceID As _
Int32, _
ByVal cMidi As Int32, _
ByVal dwCallback As _
Int32, _
ByVal dwInstance As _
Int32, _
ByVal fdwOpen As _
Int32) As Int32
Declare Function midiStreamClose Lib "winmm.dll" (ByVal hms As Int32) As _
Int32
Declare Function midiStreamOut Lib "winmm.dll" (ByVal hms As Int32, _
ByRef pmh As MIDIHDR, _
ByVal cbmh As Int32) As _
Int32
Declare Function midiStreamRestart Lib "winmm.dll" (ByVal hms As Int32) As _
Int32
Declare Function midiOutPrepareHeader Lib "winmm.dll" ( _
ByVal hMidiOut As _
Int32, _
ByRef _
lpMidiOutHdr As _
MIDIHDR, _
ByVal uSize As _
Int32) As Int32
Declare Function midiOutGetErrorText Lib "winmm.dll" Alias _
"midiOutGetErrorTextA" ( _
ByVal err As Int32, _
ByVal lpText As String, _
ByVal uSize As Int32) As Int32 Jetzt habe ich folgenden Code geschrieben um Midi messages auszugeben:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Button1.Click
Dim StreamHandle As Int32
Dim xVal, zVal, Entfernung As Double
midiStreamOpen(StreamHandle, Datenspeicher.PosXMidiPortID, 1, 0, 0, 0)
Dim MidiEventx As New MIDIEVENT
Dim DTIME As Int32 = 0
Dim midout As New MIDIHDR
Dim errortext As String = Space(128)
MidiEventx.dwDeltaTime = 0
MidiEventx.dwStreamID = 0
MidiEventx.dwEvent = &H7F0B0000 'Bedeutet: 7F=Wert 127,0B=
' Controllernummer11,00=Channel 0, 00= Shortmessage
Dim myHandle = GCHandle.Alloc(MidiEventx, GCHandleType.Pinned)'
' HIER IST DER FEHLER
midout.lpData = myHandle.AddrOfPinnedObject.ToInt32
midout.dwBufferLength = Marshal.SizeOf(midout.lpData)
midout.dwBytesRecorded = Marshal.SizeOf(MidiEventx.dwEvent)
midout.dwFlags = 0
Dim midiheaderhandle = GCHandle.Alloc(midout, _
GCHandleType.Pinned)
err = midiOutPrepareHeader(StreamHandle, midiheaderHandle, _
Marshal.SizeOf(midout))
midiOutGetErrorText(err, errortext, 128)
midiStreamOut(StreamHandle, midout, Marshal.SizeOf(midout))
err = midiStreamRestart(StreamHandle)
err2 = midiStreamClose(StreamHandle)
End Sub Beim Ausführen dieses Codes bekomme ich in der oben Markierten Zeile
eine ArgumentException: "Das Objekt enthält keine primitiven Daten."
Laut Hilfe muss an midistreamprepareHandler ein Zeiger auf eine MidiHDR Structure übergeben werden. wie mache ich das?
Ich habe ein paar c++ beispiele gefunden, aber die bringen mich nicht weiter, da man die möglichkeiten mit den Zeigern in VB.net ja nicht mehr hat, oder täusche ich mich da?
Und eine weitere Frage:
Wie kann ich als Timebase den SMPTE timecode einstellen (ich möchte bei meiner Zeiteinteilung nicht abhängig vom Tempo sein)
Ich hoffe ihr könnt mir helfen! |