| |
VB.NET - Fortgeschrittenenochmals MIDI In... | | | Autor: Bunneh | Datum: 20.05.10 15:05 |
| Hallo allerseits,
ich schreibe gerade ein Programm, das unter anderem MIDI Signale von einem Keyboard empfangen und dann interpretieren soll. Nach stundenlangem Googlen bin ich nicht wesentlich weiter. Mir fehlt der entscheidende Schritt, dass ein event bei Tastendruck ausgelöst wird, dem der MIDI-Befehl übergeben wird. Hier im Forum gab es die bis jetzt beste Hilfe (http://www.vbarchiv.net/forum/read.php?id=14&t=2752&i=2752&v=f), aber leider funktioniert das Beispiel dort nicht ohne weiteres...
Hier ist mein bisheriger Code: Diese Klasse wird in einem Minimalbeispiel auf Button_Click erstellt. Es erscheint einmal die msgbox "Midi-Test", wenn die Klasse erstellt wird und ich .OpenMIDI aufrufe, aber sonst passiert nichts...
Public Class MIDI_Handler
Declare Function midiInOpen Lib "winmm.dll" (ByRef lphMidiIn As Integer, _
ByVal devIDIn As Integer, _
ByVal cbfuncIn As test, ByVal _
cbdataIn As Integer, _
ByVal cboptionsIn As Integer) _
As Integer
Public Const CALLBACK_FUNCTION = &H30000
Public Const MM_MIM_OPEN = &H3C1
Public Const MM_MIM_CLOSE = &H3C2
Public Const MM_MIM_DATA = &H3C3
Private Const MIDI_IO_STATUS = &H20&
Public MidiLocation
Public Delegate Function test(ByVal hmidiIn As Integer, ByVal wMsg As _
Integer, _
ByVal dwInstance As Integer, ByVal dwParam1 _
As Integer, _
ByVal dwParam2 As Integer) As Boolean
Public Function MidiInProc(ByVal hmidiIn As Integer, ByVal wMsg As Integer, _
ByVal dwInstance As Integer, _
ByVal dwParam1 As Integer, ByVal dwParam2 As _
Integer) As Boolean
MessageBox.Show("Midi-Test")
End Function
Public Sub OpenMIDI()
Dim rcin As Integer
rcin = midiInOpen(MidiLocation, 0, AddressOf MidiInProc, 0, _
CALLBACK_FUNCTION)
End Sub
End Class Hat jemand eine Idee, wie es weitergeht? Danke im Voraus für jegliche Hilfe! | |
Re: nochmals MIDI In... | | | Autor: Bunneh | Datum: 02.06.10 11:24 |
| hmm, scheint ein relativ spezielles Thema zu sein ;)
Kann mir jemand sagen, ob ich da schon grundsätzlich was bei der Einbindung der Funktionen bzw. Event-Definition falsch gemacht habe? Oder sieht das gut aus? Vielleicht liegt es ja daran.
Und abermals danke für's Lesen des Addendums! | |
Re: nochmals MIDI In... | | | Autor: DaveS (Moderator) | Datum: 02.06.10 13:21 |
| Tja, wenn ich solchen extrem schlecht formattierten Code sehe glaube ich nicht, dass jemand mir zumutet sowas zu lesen.
Man kann es auch zB so machen:
Public Class MIDI_Handler
Declare Function midiInOpen Lib "winmm.dll" ( _
ByRef lphMidiIn As Integer, _
ByVal devIDIn As Integer, _
ByVal cbfuncIn As test, _
ByVal cbdataIn As Integer, _
ByVal cboptionsIn As Integer) _
As Integer
Public Const CALLBACK_FUNCTION = &H30000
Public Const MM_MIM_OPEN = &H3C1
Public Const MM_MIM_CLOSE = &H3C2
Public Const MM_MIM_DATA = &H3C3
Private Const MIDI_IO_STATUS = &H20&
Public MidiLocation
Public Delegate Function test( _
ByVal hmidiIn As IntPtr, _
ByVal wMsg As UInteger, _
ByVal dwInstance As Integer, _
ByVal dwParam1 As Integer, _
ByVal dwParam2 As Integer) As Boolean
Public Function MidiInProc( _
ByVal hmidiIn As Integer, _
ByVal wMsg As Integer, _
ByVal dwInstance As Integer, _
ByVal dwParam1 As Integer, _
ByVal dwParam2 As Integer) As Boolean
MessageBox.Show("Midi-Test")
End Function
Public Sub OpenMIDI()
Dim rcin As Integer
rcin = midiInOpen(MidiLocation, 0, AddressOf MidiInProc, 0, _
CALLBACK_FUNCTION)
End Sub
End Class Leider habe ich keine Midi-Geräte um sowas zu testen und kenne mich ohnehin nicht besonders gut aus. Von Windows Signatur sind mehrere Parameter als DWORD_PTR deklariert, was bei 64Bit Windows ein (.Net) Long (oder eventuell IntPtr) wäre. Handles wie hMidiIn sollten immer als IntPtr deklariert werden. Ob das hier relevant ist hängt von deinem Betriebssystem (und den Build-Optionen) ab.
Brauchst du nicht irgendwo MidiInStart()?
________
Alle Angaben ohne Gewähr. Keine Haftung für Vorschläge, Tipps oder sonstige Hilfe, falls es schiefgeht, nur Zeit verschwendet oder man sonst nicht zufrieden ist | |
Re: nochmals MIDI In... | | | Autor: Bunneh | Datum: 28.08.10 15:45 |
| Hallo allerseits!
Dave, du hast völlig recht: Das hätte ich schöner formatieren können. Sorry dafür, es war mein erster Post!
Ich habe das Programm nach längerer Jobbedingter Ruhephase nun zum Laufen gebracht und wollte als Abschluss noch meine Lösung für zukünftige Generationen aufzeigen.
Es hat tatsächlich MidiInStart() gefehlt. Eine extreme Fehlerquelle in diesem Zusammenhang ist die saubere Verwendung von Datentypen (32bit, 64bit, 8bit Integer/Byte/Long etc), sowie die saubere Trennung zwischen Pointern und Daten mit ByRef und ByVal. Unten beschriebene Klasse gibt nun über debug.print den Timestamp sowie die Nummer der über MIDI gedrückten Taste auf einem Digitalpiano aus. Es sind noch einige überflüssige Zeilen darin (die Errorcodes werden nicht verwendet und die MIDIHDR und MidiInAddBuffer ebenfalls nicht.
Ich hoffe, damit ist auch anderen geholfen, und wünsche euch allen viel Erfolg beim MIDI-Programmieren
Imports System.Runtime.InteropServices
Public Class MIDI_Handler
Structure MIDIHDR
Dim lpData As String
Dim dwBufferLength As Integer
Dim dwBytesRecorded As Integer
Dim dwUser As Integer
Dim dwFlags As Integer
Dim lpNext As Integer
Dim Reserved As Integer
Dim dwOffset As Integer
<VBFixedArray(4)> Dim dwReserved() As Integer
Public Sub Initialize()
ReDim dwReserved(4)
End Sub
End Structure
Structure MIDIMSG
Dim MIDIStatus As Byte
Dim MIDIByte1 As Byte
Dim MIDIByte2 As Byte
Dim Garbage As Byte
End Structure
Public MidiMessage As MIDIMSG
Public Bytes(3) As Byte
Public Const MMSYSERR_BASE As Short = 0
Public Const MMSYSERR_NOERROR As Short = 0 ' no error
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 midiInAddBuffer Lib "winmm.dll" ( _
ByVal hMidiIN As IntPtr, _
ByRef lpMidiInHdr As MIDIHDR, _
ByVal uSize As Integer) _
As Integer
Declare Function midiInPrepareHeader Lib "winmm.dll" ( _
ByVal hMidiIN As IntPtr, _
ByRef lpMidiInHdr As MIDIHDR, _
ByVal uSize As Integer) _
As Integer
Declare Function midiInOpen Lib "winmm.dll" ( _
ByRef lphMidiIn As IntPtr, _
ByVal devIDIn As Integer, _
ByVal cbfuncIn As test, _
ByVal cbdataIn As Integer, _
ByVal cboptionsIn As Integer) _
As Integer
Declare Function midiInClose Lib "winmm.dll" ( _
ByVal hMidiIN As Integer) _
As Integer
Declare Function midiInStart Lib "winmm.dll" ( _
ByVal hMidiIN As IntPtr) _
As Integer
Declare Function midiInGetNumDevs Lib "winmm.dll" () _
As Integer
Public Const CALLBACK_FUNCTION = &H30000
Public Const MM_MIM_OPEN = &H3C1
Public Const MM_MIM_CLOSE = &H3C2
Public Const MM_MIM_DATA = &H3C3
Private Const MIDI_IO_STATUS = &H20&
Public MidiLocation As IntPtr
Public Delegate Function test( _
ByVal hmidiIn As IntPtr, _
ByVal wMsg As UInteger, _
ByVal dwInstance As IntPtr, _
ByVal dwParam1 As IntPtr, _
ByVal dwParam2 As IntPtr) As Boolean
Public Function MidiInProc( _
ByVal hmidiIn As IntPtr, _
ByVal wMsg As Integer, _
ByVal dwInstance As IntPtr, _
ByVal dwParam1 As IntPtr, _
ByVal dwParam2 As IntPtr) As Boolean
'Debug.Print("wMsg: " & wMsg)
'Debug.Print("dwInstance: " & dwInstance)
Debug.Print("dwParam1 (message): " & dwParam1.ToInt32)
Debug.Print("dwParam2 (Timestamp): " & dwParam2.ToInt32)
Bytes = BitConverter.GetBytes(dwParam1.ToInt32)
MidiMessage.MIDIStatus = Bytes(0)
MidiMessage.MIDIByte1 = Bytes(1)
MidiMessage.MIDIByte2 = Bytes(2)
Debug.Print("MIDI Status:" & MidiMessage.MIDIStatus)
Debug.Print("MIDI Byte 1:" & MidiMessage.MIDIByte1)
Debug.Print("MIDI Byte 2:" & MidiMessage.MIDIByte2)
End Function
Public Sub OpenMIDI()
Dim rcin As Integer
Dim rc2 As Integer
Dim intTotalDevIDs As Integer
Dim devID As Integer = 0
intTotalDevIDs = midiInGetNumDevs()
'rc2 = midiInClose(MidiLocation)
rcin = midiInOpen(MidiLocation, devID, AddressOf MidiInProc, 0, _
CALLBACK_FUNCTION)
rc2 = midiInStart(MidiLocation)
End Sub
End Class | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
Neu! sevDTA 3.0 Pro
SEPA mit Kontonummernprüfung
Erstellen von SEPA-Dateien mit integriertem BIC-Verzeichnis und Konto- nummern-Prüfverfahren, so dass ungültige Bankdaten bereits im Vorfeld ermittelt werden können. Weitere InfosTipp des Monats Access-Tools Vol.1
Über 400 MByte Inhalt
Mehr als 250 Access-Beispiele, 25 Add-Ins und ActiveX-Komponenten, 16 VB-Projekt inkl. Source, mehr als 320 Tipps & Tricks für Access und VB
Nur 24,95 EURWeitere Infos
|