vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
SEPA-Dateien erstellen inkl. IBAN-, BLZ-/Kontonummernprüfung  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Fortgeschrittene
nochmals 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!
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

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!
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: nochmals MIDI In... 
Autor: ModeratorDaveS (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

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

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
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

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

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel