Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

MIDI PLAYER WPF VB 2008


Information sur la source

Description

Cliquez pour voir la capture en taille normale
Un lecteur de Midifile en Visual Basic 2008 et WPF.
La structure de donnée est revue.
NET 3.5 obligatoire.

L'exemple est un lecteur de Midifile, mais la classe MidiData permet de  manipuler les données Midi comme bon vous semble.

La conso de ressource processeur reste trés faible (entre 1 et 2 %).

Ne gère pas (encore ...) les changement de signature dynamique.

Par défault, le programme boucle sur les 4 premières mesures.

Si vous trouvez des bugs, n'hésitez pas à reporter.

Quelques contrôles pour gèrer les mesures et le tempo ... en cadeau !

Merci

Afyn - Navedac - Le savoir faire des cancres
 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Commentaires et avis

signaler à un administrateur
Commentaire de EBArtSoft le 08/07/2008 22:54:52 administrateur CS

C'est pas mal du tout tu as fais d'enorme progres je trouve...

Si je peux me permettre quelques suggestions :

Plusieurs classes par fichier .vb
'Peut être remplacé par
Un fichier .vb par classe

Dim i As Integer
For i = 0 To 31
'peut être remplacé par :
For i As Integer = 0 To 31

If openFileDialog.ShowDialog() = True Then
'Peut être remplacé par :
If (openFileDialog.ShowDialog()) Then

If TimerID <> 0 Then
'Peut être remplacé par
If (TimerID) Then

Dim objNewMember As New MidiEvent
...
objNewMember = Nothing
'Peut être remplacé par :
Using objNewMember As New MidiEvent
...
End Using

et d'autres broutilles

Bravo

@+

signaler à un administrateur
Commentaire de NHenry le 09/07/2008 09:45:37

EBArtSoft, désolé de te contredire, mais d'après mes connaissances :
- Using est réservé aux classes implémentant IDisposable, alors que (d'après ce que j'ai vu MidiEvents n'est pas dans ce cas).

Ensuite concernant :
If TimerID <> 0 Then
'Peut être remplacé par
If (TimerID) Then

C'est faux, il suffit de mettre Option Strict à On et le compilateur hurlera pour signaler qu'il ne peux pas caster implicitement un entier en un booléen.


Afyn>
Pour les perfs, évite CType quand tu as un héritage clair (pas d'adaptation Int -> Long par exemple) mais préfère DirectCast, c'est plus rapide.

#  Dim Trk As New Track
#
# ' Efface le contenu des pistes
# For Each Trk In mCol.Values

# Next Trk

Tu peux définit uniquement :
Dim Trk As Track 'pas besoin du New à chaque fois.
Mais le mieux (comme le dit EbArtSoft) :
# For Each Trk as track In mCol.Values
# Next Trk

Pour indiquer par des commentaires à quoi servent tes méthodes, events, delegates, enum, ..., je te conseil d'utiliser les 3 ' , cela fera une infobulle, ce sera un peu mieux.


Voilà pour un premier jet.

signaler à un administrateur
Commentaire de Afyn le 09/07/2008 10:30:21

Merci pour vos commentaires.

Pour les commentaires, voilà en gros le fonctionnement :
Les datas Midi sont stockés dans une hiérachie d'objets.

Pour rappel, les données Midi peuvent avoir 2 ou 3 octets, D1, D2, (D3).
D1 est divisé en deux partie.
D1H correspond au type de message (NOTE_ON par exe)
D1L au canal Midi de 0 à 15
D1H et D1L peuvent être ignoré si leurs valeurs est identique
au message Midi précedent (running status)
D2 pour un msg NOTE_ON correspond au numéro de la note.
D3 pour un msg NOTE_ON correspond à la vélocité (force dela note)

Chaque MidiEvent est stocké dans une collection MidiEvents

Tick représente la position temporelle (absolue) de chaque MidiEvent
La collection Ticks est l'ensemble de tous les Tick ...
L'index de cette collection est la position temporelle en Tick

Track représente une piste et Tracks la collection

Tracks(0).Ticks(0).MidiEvents(0).msg représente le msg à envoyer.

Envoyer un msg prend 300µs. (je vous laisse calculer le débit !)

Dans le cas d'une lecture synchrone, on "Pulse" les msg  à intervalle
régulier.
Le "Pulsage" est dans un thread différent de l'application. (délégate)
La durée de cet intervalle correspondra au Tempo du morceau.

L'avantage de tout ça ?
Cette façon de structurer les données permet de les modifier pendant
l'exécution du morceau, alors que sur beaucoup de séquenceur il
faut arrêter l'exécution pour pouvoir modifier une note.

La génération des NOTE_OFF est "à la volée"

EB m'a beaucoup aidé dans la conception de cette structure.
Elle est souple et performante. (Insérer 10 000 events prend 20 ms)
Il est possible que d'autre façon de faire existe, mais ce que
j'ai pu lire sur le NET était 100 fois plus compliqué.

Le lecteur de MidiFile n'est qu'un exemple d'utilisation de
cette structure hiérachique. Il est volontairement simple.
Le code dans MainForm n'est pas trés important puisque
beaucoup de choses sont dans la fichier MidiData.VB

Evidemment, il reste du boulot, mais le concept est solide.

signaler à un administrateur
Commentaire de Patrice99 le 09/07/2008 16:28:59

Rien que pour le plaisir de rajouter mon grain de sel, je dirai que EBArtSoft n'est plus à la page depuis plusieurs mois, car il suffit d'activer Option Infer à On pour laisser la seule ligne suivante, qui définira i en tant qu'Integer :
For i = 0 To 31
Et plusieurs classes par fichier .vb est parfois plus lisible que des milliers de fichiers qui trainent partout.

signaler à un administrateur
Commentaire de EBArtSoft le 09/07/2008 17:26:46 administrateur CS

1) IDIsposable c'est une et une seule methode ("IDIsposable.Dispose") à implementer. Je ne vois la rien de bien mechant à ajouter aux objets deja presents.

2) Concernant l'"Option Strict On", il est reconnu de fait que l'activer sur la solution complete ne rend pas le code plus "securisé", plus "fiable" ou plus "aisé" surtout quand on manipule des objet COM. Autant l'employer partiellement lorsque cela est necessaire grace à

#Begin Option Strict On/Off
#End Option Strict On/Off

Sauf bien sur si on laisse les outils de validation faire le travail à sa place.

3) "For Each Item In Items" Utilise IEnumerable ce qui rend l'indexation plus lente qu'avec un simple "For I=1 To ItemsCount ... Items(I)"

4) Option Infer est du meme gout que strict il deresponsabilise le developpeur et ne fait pas toujours le bon choix par exemple :

dim a as double
a = 100
For I = 0 to A

I sera du type double hors ce n'est pas forcement ce que le developpeur veux. On en revient donc à la declaration explicite.

Concernant l'utilisation de plusieurs fichiers c'est un avis purement personnel. Je connais suffisamment Afyn pour lui exposer mes opinons même si elles ne sont pas "à la page" sans craindre quelconques jugements arbitraires.

signaler à un administrateur
Commentaire de Afyn le 09/07/2008 22:25:24

Moi je respecte beaucoup beaucoup beaucoup EBArtSoft !

Afyn - Navedac

signaler à un administrateur
Commentaire de EBArtSoft le 09/07/2008 22:56:29 administrateur CS

Moi j'aime le beurre de cacahuete

signaler à un administrateur
Commentaire de Patrice99 le 10/07/2008 08:16:39

Moi j'aime bien titillier les pinailleurs, cela m'a permis d'apprendre que #Begin Option existe :-)

signaler à un administrateur
Commentaire de NHenry le 10/07/2008 09:47:12

Merci EBArtSoft pour #begin, je ne connaissais pas (mais ne fonctionne que avec 2008, pas avec 2005).

Mais comme je manipule rarement des objets COM, Strict est toujours à On.
Concernant Infer, c'est revenir (à mon avis) à Strict Off.
Concernant le For Each, je viens d'apprendre un truc.
Pour IDisposable, cela ne coute rien de l'ajouter, mais ce n'est pas dans mon habitude; et d'ailleurs, ma remarque concernant la classe était juste, elle ne l'implémentait pas.

Merci pour cette mise au point.

signaler à un administrateur
Commentaire de Afyn le 10/07/2008 10:28:49

Bonjour les animateurs ...
Puisque tout le monde y va plein pot, je vous fait part, moi aussi, de mes idées.

Le plus dur pour un amateur comme moi, c'est la relecture du code que l'on a écrit.
Au bout d'un moment, on relit plus rien du tout !

C'est dur également de découper un code en parties facilement appréhendable par
d'autres.

Sur cette source, vous voyez le résultat pratiquement final de quelques années
de bricolage. Il y a presque autant de temps passé à débattre de la façon de
faire que de temps à écrire le programme.
Il faut avoir une vue d'ensemble de ce que l'on veut faire en même temps
qu'une vue des nombreux détails à régler.
Et rajoutez à cela le nombre de lignes de code que j'ai mis à la poubelle
après avoir décidé que ça n'apportait rien !

Donc voilà, je ne vous remercierai jamais assez de votre aide. Et EBArtSoft
a énormément pris de son temps pour me guider et donc lui je le remercie
encore plus particulièrement.

Le but recherché de cette source est de permettre de manipuler les données Midi.

Je crois que ce but est atteint.

J'avais aussi dans l'idée de donner un Kit " prêt à l'emploi ". Cet l'avis
des personnes qui réutiliserai ce travail qui pourrait être intéressant, dans
le sens des capacités du Kit et de ses limites.

Donc ... lachez du commentaire !

Je prend tout.

Merci encore

Afyn - Navedac
Le savoir faire des cancres



signaler à un administrateur
Commentaire de Patrice99 le 10/07/2008 10:37:19

> Concernant Infer, c'est revenir (à mon avis) à Strict Off.

Absolument pas du tout ! Le typage reste un typage fort, rien à voir avec du typage implicite : il suffit de laisser la souris sur la variable pour se convaincre de l'inférence de son type. Il ne s'agit pas d'un gadget pour les fainéants, mais d'une fonctionnalité requise pour l'implémentation de Linq.

signaler à un administrateur
Commentaire de Afyn le 10/07/2008 10:37:36

Ha oui ... je cherche à remplacer le Texte "Open" & "Start" dans la ToolBar par des icones vectorielles (pas de png gif ou autres donc) ... si quelqu'un à une idée sur
la façon de procéder ?

Merci
Afyn - Navedac
Le savoir faire des cancres

signaler à un administrateur
Commentaire de Patrice99 le 03/08/2008 09:21:13

#Begin Option Strict On/Off
#End Option Strict On/Off
n'existe pas : il ne s'agit que d'une suggestion d'un internaute.

signaler à un administrateur
Commentaire de Afyn le 04/08/2008 13:35:34

Bonjour :

-> NHenry je viens de comprendre ceci :
Pour indiquer par des commentaires à quoi servent tes méthodes, events, delegates, enum, ..., je te conseil d'utiliser les 3 ' , cela fera une infobulle, ce sera un peu mieux.

en fait les 3' correspondent au code xml ? par exemple

''' <summary>
''' MIDI Constant
''' </summary>
''' <remarks></remarks>

Effectivement ça fait une info bulle :) (C'est documenté ou ?)

-> Patrice : Oui j'ai pas ces options moi non plus ...

Afyn - Navedac
Le savoir faire des cancres


signaler à un administrateur
Commentaire de Ricomat le 08/11/2008 14:40:53

Avec Windows Vista,
Les midi not off ne sont pas envoyées lorsque l'on appui sur "stop" dans ton programme.
J'ai l'impression que MidiOutReset ne fonctionne pas sur Vista (ok sur XP). les nappes ne s'arrêtent pas.

Si tu as une solution, je suis preneur, j'ai le même problème dans une de mes appli^^.

++

signaler à un administrateur
Commentaire de NHenry le 08/11/2008 18:27:05

Afyn>
Dsl, j'ai pas du voir passer le mail.
Donc, c'est enregistrer dans le xml qui porte le même nom de l'exécutable (ou la DLL).

signaler à un administrateur
Commentaire de Afyn le 08/11/2008 21:15:26

Ricomat j'ai une version un peu plus avancée si tu l'as veux ?

Pm moi une adresse maile je te l'envoie

Afyn - Navedac

signaler à un administrateur
Commentaire de Ricomat le 09/11/2008 16:59:01

Merci^^ mon adresse est eric.matras@free.fr
mon site http://www.rickforce.fr

J'ai ce matin remplacé dans mon appli les midiOutReset par :

    Public Function StopMidiOut(Optional ByVal Canal As Integer = Nothing) As Integer
        If Canal = Nothing Then
            For i As Integer = 0 To 15
                StopMidiMess(i)
            Next
        Else
            StopMidiMess(Canal)
        End If
    End Function

    Private Function StopMidiMess(ByVal Canal As Integer) As Integer
        WMM.midiOutShortMsg(hMidiOut, ControlChange.All_Note_Canal_off Or Canal) '&7BB0
        WMM.midiOutShortMsg(hMidiOut, ControlChange.Control_off Or Canal) '&H79B0
    End Function

et ca marche sous vista pour ma part :).

signaler à un administrateur
Commentaire de Afyn le 10/11/2008 11:04:55

Ricomat ->
Je t'ai envoyé la dernière version.
Elle est un peu plus complexe au niveau structure de données Midi.

Pour les All Notes OFF, je ne me suis pas penché dessus.

Peut tu me dire ce que tu penses de la structure des classes
Track(s)-> Tick(s)-> MidiEvent(s) ?

Merci d'avance pour ta coop

Afyn - Navedac

signaler à un administrateur
Commentaire de Ricomat le 10/11/2008 12:19:12

merci pour ton envoi :).

Je vois que tu gères maintenant un piste NoteOffTrack :), qui te sert à stopper les NOTE ON en cours.
Si l'on commente les lignes suivantes, les sons ne s'arrêtent pas, je pense que tu peux enlever le MidiOutReset qui se trouve un peu avant dans ton code. le MidiOutReset n'a pas vraiment l'air de fonctionner sous vista. sinon bien vu ;).

' Reset le MIDI                
For Each Tck As Tick In NoteOffTrack.Ticks
     For Each Evt As MidiEvent In Tck.MidiEvents
          Call WinMM.midiOutShortMsg(hMidiOut, Evt.Msg)
     Next
Next
NoteOffTrack.Clear()

Pour tes class Track and co, dès que j'ai un peu de temps, je regarde de plus près, mais je pense pas avoir grand chose à dire de plus que les autres :). Je m'en était déja bien inspiré suite à tes précédentes publications :).

signaler à un administrateur
Commentaire de Afyn le 10/11/2008 12:25:43

Pour plus de clarté :

Les MidiEvents Notes OFF n'existent pas dans la structure objet.
Ils vont être créés lors de l'envoie d'un Msg Note_On dans une Track temporaire et positionné sur le Tick qui correspont au Tick de la Note_On + la durée de la Note_On.

C'est un mécanisme à la vollée !

Voilà

Afyn - Navedac

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Interrompre l'exécution d'un d'un fichier midi [ par JCLK ] Je sais comment jouer un fichier midi. Je sais aussi l'interrompre avec les touches "ctrl" et "pause". Je voudrais donc savoir comment l'interrompre a lire un MIDI [ par Nic.C ] comment faire lire un fichier midi en cliquant sur un bouton et l'arreter en cliquant sur un autre boutton sans utiliser le controle OLE Lecture sur le port MIDI [ par Nical ] Bonjour, je dispose d'un appareil MIDI branché sur le port MIDI/Joystick de ma carte son, et je voudrais récupérer ces données avec VB 6.0.....Merci d Piste Midi [ par Mikey ] Bonjour Comment lire une seule piste (channel) d'un fichier midi en VB6? Fichiers MIDI [ par Funcman ] J'aimerais savoir comment on fait pour jouer des musiques MIDI et sans que ca bloque le system... MERCI à tous. écouter un MIDi dans une api, c'est possible ? [ par hErectus ] Slt !Je vien de terminer une petite aplikation vb6, et je voudrais écouter un fichier midi en même temp.serait-il possible que qq m'indike comment com Fichier Midi [ par KobbA ] heu.. Pourriez vs etre plus preci qd vs dites "beh c simple, utilise le control mci32.ocx de windows pour jouer un midi" parce que ça pour moi ça veut jouer un midi en fond [ par naney ] comment on fais pour jouer un fichier midi en fond c'est pour un jeu je veu qui ce maite en lecture puis par un bouton je pe le couper est le remaitre Aide sur fichier MIDI [ par fab ] bonjourqq1 aurait une solution pour ecouter une music (fichier *.mid ) dans un fichier resource ?Je compose quelques zik en midi, et je voudrais pas l


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,811 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.