Midi in piano

Soyez le premier à donner votre avis sur cette source.

Vue 11 446 fois - Téléchargée 1 159 fois

Description

Bonjour
Voici une version révisée du programme Midi-in-Vb2008 de monsieur Navedac. Ce programme m'a beaucoup aidé pour m'initier à VB2008 alors que je programmais en VB4, ce qui ne me permettait pas de réaliser des logiciels recevant des messages midi. J'en remercie l'auteur et VBFrance.

Le programme original datant de 2006 fonctionne, mais partiellement. En effet, n'exploitant pas l'information "n° de canal" des messages Midi entrant, il ne pouvait afficher que les notes transmises par le canal midi 1 et la routine d'affichage en couleur selon le canal ne servait à rien (en plus d'être mal placée).

J'ai renommé le programme en Midi In Piano. Seul de code de la classe a été modifié. La partie contenant la déclaration des procédures est inchangée. Maintenant, le logiciel affiche bien toutes les notes reçues, avec une couleur différente selon le canal.
les modifications que j'ai effectuées sont indiquées en rem au début du texte.

Source / Exemple :


'***************************************************************************************
' © Midi In Piano
' © Création - 09/07/2006
' © Revision - 11/07/2006
' © Afyn - Navedac - Le savoir faire des cancres
' Corrigé le 25/07/2009 par Jean-Paul VERPEAUX 
' Le programme original n'exploitait pas l'info canal midi et ne pouvait afficher que les notes du canal 1
' La boucle "j" et l'affectation des 16 couleurs ne servaient strictement à rien.
' J'ai rajouté :
' - les variables globales "canal" et "ccolor ()",
' - le code pour extraire le canal du code de status
' - le code pour attribuer aux notes une couleur différente selon le canal

Option Strict Off
Option Explicit On
Imports System.Drawing.Bitmap
Imports System
Imports System.Runtime.interopServices
Imports System.Text

Public Class PianoRoll
    Dim KeyCol As New System.Collections.Generic.List(Of UserControl)

    ' Coordonnées de départ pour déplacer la Form
    Private X_Piano As Short
    Private Y_Piano As Short
    Private Oct As Short
    Private Xpose As Short = -12

    Dim canal As Byte ' canal midi
    Dim ccolor(16) As System.Drawing.Color ' couleur selon canal
    Dim hMidiIn As Integer
    ' Délégué pour le callback Midi In
    Private DelgMidiIn As New MidiDelegate(AddressOf MidiInProc)
    ' Permet de transmettre les paramètre à la Win Form
    Delegate Sub SetParamCallback(ByVal [Param] As Byte)
    ' vpx
    'Delegate Sub SetParamCallback(ByVal [Param] As Byte, ByVal [canal] As Byte)
    Dim DelgParamON As New SetParamCallback(AddressOf TouchOn)
    Dim DelgParamOff As New SetParamCallback(AddressOf TouchOff)

    Private Sub PianoRoll_Load(ByVal sender As System.Object, _
                               ByVal e As System.EventArgs) _
                               Handles MyBase.Load
        Dim i As Short
        Dim Swk As UserControl

        ' modif vpx
        ccolor(0) = Color.Red
        ccolor(1) = Color.Gray
        ccolor(2) = Color.Orange
        ccolor(3) = Color.Yellow
        ccolor(4) = Color.GreenYellow
        ccolor(5) = Color.CornflowerBlue
        ccolor(6) = Color.Blue
        ccolor(7) = Color.Magenta
        ccolor(8) = Color.Silver
        ccolor(9) = Color.Salmon
        ccolor(10) = Color.LightSalmon
        ccolor(11) = Color.BurlyWood
        ccolor(12) = Color.Lime
        ccolor(13) = Color.Cyan
        ccolor(14) = Color.Fuchsia
        ccolor(15) = Color.Purple

        For i = 0 To 127
            Swk = New UserControl           ' Créé L'objet !
            With Swk
                .BringToFront()
                .Visible = False
                .Tag = i
                .Width = 8
                .Height = 8
                Select Case i
                    Case 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120
                        .Top = 96
                        .Left = ((i + Xpose) * 10) + 3
                    Case 1, 13, 25, 37, 49, 61, 73, 85, 97, 109, 121
                        .Top = 59
                        .Left = ((i + Xpose) * 10)
                    Case 2, 14, 26, 38, 50, 62, 74, 86, 98, 110, 122
                        .Top = 96
                        .Left = ((i + Xpose) * 10)
                    Case 3, 15, 27, 39, 51, 63, 75, 87, 99, 111, 123
                        .Top = 59
                        .Left = ((i + Xpose) * 10) + 2
                    Case 4, 16, 28, 40, 52, 64, 76, 88, 100, 112, 124
                        .Top = 96
                        .Left = ((i + Xpose) * 10) - 2
                    Case 5, 17, 29, 41, 53, 65, 77, 89, 101, 113, 125
                        .Top = 96
                        .Left = ((i + Xpose) * 10) + 5
                    Case 6, 18, 30, 42, 54, 66, 78, 90, 102, 114, 126
                        .Top = 59
                        .Left = ((i + Xpose) * 10) + 2
                    Case 7, 19, 31, 43, 55, 67, 79, 91, 103, 115, 127
                        .Top = 96
                        .Left = ((i + Xpose) * 10) + 2
                    Case 8, 20, 32, 44, 56, 68, 80, 92, 104, 116
                        .Top = 59
                        .Left = ((i + Xpose) * 10) + 1
                    Case 9, 21, 33, 45, 57, 69, 81, 93, 105, 117
                        .Top = 96
                        .Left = ((i + Xpose) * 10) - 1
                    Case 10, 22, 34, 46, 58, 70, 82, 94, 106, 118
                        .Top = 59
                        .Left = ((i + Xpose) * 10) + 1
                    Case 11, 23, 35, 47, 59, 71, 83, 95, 107, 119
                        .Top = 96
                        .Left = ((i + Xpose) * 10) - 4
                End Select
            End With
            KeyCol.Add(Swk)             ' Rajoute un pointeur sur l'objet dans la collection
            Me.Controls.Add(Swk)        ' Rajoute un pointeur sur ME.controls
        Next i

        '*** On unitialise le Midi In ***
        Dim MidiInCaps As New MIDIINCAPS
        Dim DrvNumber As Long

        For DrvNumber = 0 To (WinMM.midiInGetNumDevs - 1)            'on parcours tous les drivers
            WinMM.midiInGetDevCaps(DrvNumber, _
                                   MidiInCaps, _
                                   Marshal.SizeOf(MidiInCaps))
            Dim MenuItem As New ToolStripMenuItem
            MenuItem.Checked = False
            MenuItem.Tag = DrvNumber
            MenuItem.Text = Encoding.Unicode.GetString(MidiInCaps.ProductName)
            Me.Cms1.Items.Add(MenuItem)
        Next

    End Sub

    Private Sub Cms1_ItemClicked(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles Cms1.ItemClicked
        Dim midiError As Integer
        Dim MenuItem As ToolStripMenuItem
        For Each MenuItem In Cms1.Items
            MenuItem.Checked = False
        Next
        MenuItem = e.ClickedItem
        MenuItem.Checked = True

        ' On scanne le port Midi In
        midiError = WinMM.midiInOpen(hMidiIn, MenuItem.Tag, DelgMidiIn, 0, &H30000)
        midiError = WinMM.midiInStart(hMidiIn)
    End Sub

    Protected Sub MidiInProc(ByVal MidiInHandle As Int32, _
                         ByVal NewMsg As Int32, _
                         ByVal Instance As Int32, _
                         ByVal wParam As Int32, _
                         ByVal lParam As Int32)
        If wParam > 255 Then
            'Trace.WriteLine("Msg " & wParam)
            Dim b() As Byte = BitConverter.GetBytes(wParam)
            canal = b(0) And &HF ' recupere le canal
            Select Case b(0) And &HF0
                Case &H90
                    If b(2) > 0 Then
                        Me.TouchOn(b(1))
                    Else
                        Me.TouchOff(b(1))
                    End If
                Case &H80 And &HF0
                    Me.TouchOff(b(1))
            End Select
        End If
    End Sub

    Private Sub TouchOn(ByVal [Param] As Byte)
        If Me.KeyCol([Param]).InvokeRequired Then
            Me.KeyCol([Param]).Invoke(DelgParamON, New Object() {[Param]})
        Else
            Me.KeyCol([Param]).Visible = True
        End If
        Me.KeyCol([Param]).BackColor = ccolor(canal)
    End Sub

    Private Sub TouchOff(ByVal [Param] As Byte)
        If Me.KeyCol([Param]).InvokeRequired Then
            Me.KeyCol([Param]).Invoke(DelgParamOff, New Object() {[Param]})
        Else
            Me.KeyCol([Param]).Visible = False
        End If
    End Sub

End Class

Conclusion :


Le nouveau programme affiche maintenant en couleur les notes des 16 canaux midi

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
728
Date d'inscription
samedi 4 avril 2009
Statut
Membre
Dernière intervention
30 mars 2014
6
Bonjour Afyn,

Tu m'écris :

"EHJOE ^^ tu as besoin de quoi ?
Cette source est plutot destinée aux developpeurs.
(Eh)Joyeux Noël"

En réponse :
J'ai besoin d'une source qui fonctionne, et qui permettent au moins pour l'exemple de jouer trois, quatre notes avec la carte son dans un timbre piano par exemple.
Ou d'une interface plus élaborée, qui permette par exemple de choisir quelques notes (hertz en comboBox) dans le timbre des instruments qu'autorise la carte son (listBox)…
Et je ne trouve pas en vbNet10 ou 8 ou 5 !

*

Le problème est que quand je copie une source, que je la lance en mode debug, l'interface ne permet pas de faire fonctionner le code, or toute explication doit être servie par des exemples qui fonctionnent afin d'aider à la compréhension, c'est ainsi qu'on apprend à l'école : élément nouveau + exemple d'utilisation…

*

D'autant que je fais aussi quelques sources, ici :
http://www.codes-sources.com/codes_auteur/EHJOE/350129.aspx

Mais que quand je fais une source "moi" et qu'on la lance en mode debug, l'interface permet de la faire fonctionner, immédiatement, car je suis consciencieux, et je ne comprends pas qu'on se permette de mettre des sources qui ne tournent pas…
Une source ce n'est pas un exemple, une source c'est un "programme qui sert aussi d'exemple" et qui doit immédiatement fonctionner !

Or à chaque fois que je charge une source sur le thème de la carte son, ça ne marche pas, c'est horripilant !

Au plaisir, cordialement, et joyeux Noël, Joe.
Messages postés
5
Date d'inscription
dimanche 19 juillet 2009
Statut
Membre
Dernière intervention
20 décembre 2011

Le titre n'est pas de moi, et il n'a rien d'illogique :
- MIDI IN car on traite de l'arrivée des messages Midi
- PIANO car on visualise les messages reçus au moyen d'un dessin de clavier de piano.
Cordialement
J-Paul
Messages postés
608
Date d'inscription
samedi 3 août 2002
Statut
Membre
Dernière intervention
22 décembre 2016

EHJOE ^^ tu as besoin de quoi ?
Cette source est plutot destinée aux developpeurs.

(Eh)Joyeux Noël
Messages postés
728
Date d'inscription
samedi 4 avril 2009
Statut
Membre
Dernière intervention
30 mars 2014
6
Ben si je me fis au titre "MIDI IN PIANO" il faut tout sauf du piano, il ne fait rien en fait en tant que piano, faudrait donc en changer le titre peut être...

Cordialement, Joe.
Messages postés
5
Date d'inscription
dimanche 19 juillet 2009
Statut
Membre
Dernière intervention
20 décembre 2011

BONJOUR
Ce serait dommage de retirer ce code source car il fonctionne très bien.
Votre déception vient du fait que vous n'avez malheureument pas compris de quoi il s'agit.
Ce programme n'est pas destiné à produire un son de piano, ce n'est pas un instrument de musique.
C'est un programme qui permet de tester et visualiser les messages envoyés à un ordinateur par un instrument de musique (synthétiseur ou orgue) répondant à la norme MIDI (Musical Instruments Digital Interface).
L’intérêt de ce code source est surtout pédagogique car il explique les principes de la réception des messages Midi. Cette technique de programmation est très complexe et peu documentée par Microsoft. La création de logiciels musicaux serait quasi-impossible, même à des programmeurs de haut niveau si de tels exemples de code n'existaient pas. Merci encore une fois Afyn pour avoir initié cette rubrique.
Afficher les 15 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.