|
[WD14] Activation interface USB/midi (utilisation winmm.dll) |
Débuté par Dominique Durand, 13 nov. 2009 01:25 - 33 réponses |
| |
| | | |
|
| |
Posté le 13 novembre 2009 - 01:25 |
Bonjour, Je teste depuis quelques jours l'appel à l'API Winmm.dll, mais je bloque au delà des fonctions MidiOutOpen et MidiInOpen. J'ai récupéré par la fonction USBRecherche(USBPropriétéNomExplicite, "Midi") l'identifiant du port USB sur une zone définie en chaine sur 100. Les fonctions MidioutOpen et MidiInOpen (retourFonction=API("WINMM.DLL","midiOutOpen",Hmo,0,0,0,0) me retourne un code 0. Les fonctions midiOutShortMsg, MidiOutClose et MidiInClose me retournent eux un code 5 (Access is denied). Le fait de relancer les fonction Midi..Open qui me donne alors un code erreur 4 (The system cannot open the file) me laisse à penser que l'ouverture des ports était correcte au premier passage. Pourquoi alors les opérations de fermeture ne fonctionnent pas? Toutes les recherches sur les FAQ, forums et autres n'ont pu m'éclairer sur mon PB. J'ai essayé également d'envoyer des messages par la fonction "midiOutShortMsg" j'ai un code retour 5 également.
Si vous pouvez m'éclairer, je vous en remercie d'avance.
Mon code de test
retourFonction est un entier sNomexplicite est une chaîne sDescription est une chaîne sErreur est une chaîne sListe est une chaîne SIDmidi1 est une chaîne sur 100 SIDmidi2 est une chaîne sur 100
Hmo est une chaîne sur 100 sHmi est une chaîne sur 100 nInd est un entier sPériphériques est une chaîne = USBRecherche(USBPropriétéNomExplicite, "Midi") SI sPériphériques <> "" ALORS SPérif est une chaîne POUR TOUTE CHAINE SPérif DE sPériphériques SEPAREE PAR RC nInd++ SELON nInd CAS 1 : SIDmidi1 = SPérif CAS 2 : SIDmidi2 = SPérif AUTRES CAS : FIN FIN FIN
hInst est un entier hInst = ChargeDLL("WinMM.DLL") SI hInst = 0 ALORS Erreur(ErreurInfo()) RETOUR FIN Hmo = SIDmidi1 retourFonction=API("WINMM.DLL","midiOutOpen",Hmo,0,0,0,0) Info ("openout/"+retourFonction+"/"+Hmo)
Hmi = sIDmidi1 retourFonction=API("WINMM.DLL","midiInOpen",Hmi,0,0,0,0) Info ("openIn/"+retourFonction+"/"+Hmi)
retourFonction=API("WINMM.DLL","midiOutClose",Hmo) Info ("CloseOut/"+retourFonction+"/"+Hmo)
retourFonction=API("WINMM.DLL","midiInClose",Hmi) Info ("CloseIn/"+retourFonction+"/"+Hmi) |
| |
| |
| | | |
|
| | |
| |
Posté le 21 novembre 2009 - 09:25 |
Bon coté MidiOut cela va mieux je réussi à adresser les messages voulus sur plusieurs sorties midi en fonction des besoins. J'utilise avec des variables type stuctures et entiers les lignes suivantes:
nNbredevs =API("WINMM.DLL","midiOutGetNumDevs") ... POUR UDeviceID = 0 A nNbredevs-1 retourFonction=API("WINMM.DLL","midiOutGetDevCapsA",UDeviceID,&pmoc,Taille(&pmoc)) FIN ...
retourFonction=API("WINMM.DLL","midiOutOpen",&nHmo,gnDeviceOut3,0,0,0)
gnCanal = gnCanalOut3 gnCodePgm = TABLE_T_Programme_Det.COL_Cd_PM_Midi
nDwMsg = gnCanal + 192 + (gnCodePgm*256) retourFonction=API("WINMM.DLL","midiOutShortMsg",nHmo,nDwMsg)
retourFonction=API("WINMM.DLL","midiOutClose",nHmo) Reste maintenant à regler le problème de la récupération de messages Midi en IN. Voici le code que j'ai testé jusqu'à présent: Une procédure
Procedure MessagemidiIn(Hmi1 est un entier,nUMsg est un entier système,nDw1 est un entier système,nDw2 est un entier système) Trace("messageMidiIn") appelée via son adresse comme fonction de rappel et code général suivant:
MIDIINCAPSA est une structure wMid est un entier sur 2 octets wPid est un entier sur 2 octets vDriverVersion est un entier szPname est une chaîne fixe sur 32 dwSupport est un entier FIN
nNbredevs est un entier =API("WINMM.DLL","midiInGetNumDevs")
POUR UDeviceID = 0 A nNbredevs-1 retourFonction=API("WINMM.DLL","midiInGetDevCapsA",UDeviceID,&pmic,Taille(&pmic)) FIN gndeviceIn1 est un entier = 0 gnIDProced est un entier = &MessagemidiIn retourFonction = API("WINMM.DLL","midiInOpen",&nHmi,gnDeviceIn1,gnIDProced,0,0) Trace("MidiInOpen/" +retourFonction) retourFonction = API("WINMM.DLL","midiInStart",nHmi) Trace("MidiInStart/" +retourFonction)
Les codes retour sont à 0 donc à ce niveau cela semble corret. Mais je n'ai aucune indication (trace dans la procédure MessagemidiIn) de réception des messages midi qui entre sur le port IN concerné. J'ai un peu avancé mais là je bloque. L'ecoute du port midi necessite l'activation d'un traitement qui récupère le message, le traite et active des traitements complémentaires mais je prends pas le problème dans le boon sens. Y a t'il sur le forum un spécialiste des API qui pourrait m'éclairer de son savoir? |
| |
| |
| | | |
|
| | |
| |
Posté le 30 mai 2010 - 00:44 |
Si vous avez des infos , ça m'arrangerai aussi j'ai le meme probleme. J'ai essayé la fonction MidiInProc , mais , WD me réponds que c'est inconnu dans la DLL |
| |
| |
| | | |
|
| | |
| |
Posté le 30 mai 2010 - 11:49 |
Salut Laurent,
MidiInProc n'est pas une fonction qu'on peut appeler par la dll. Par contre j'ai vu une erreur dans le code de Dominique :
retourFonction = API("WINMM.DLL","midiInOpen",&nHmi,gnDeviceIn1,gnIDProced,0,0) le dernier paramètre est à zéro (dwflags) ce qui fait qu'on appelle la fonction avec un CALLBACK_NULL il n'y aura pas de mécanisme de callback donc pas d'exécution de la procédure MessagemidiIn. Il faut appeler la dll avec comme dernier paramètre CALLBACK_FUNCTION qui a pour valeur 0x30000 donc cela donne :
retourFonction =API("WINMM.DLL","midiInOpen",&nHmi,gnDeviceIn1,gnIDProced,0,0x30000)
je te garantis pas que ça va marcher mais tu peux toujours essayer. Moi je n'ai pas d'interface midi donc je peux pas essayer.
Ami calmant, J.P |
| |
| |
| | | |
|
| | |
| |
Posté le 30 mai 2010 - 21:20 |
Merci pour l'info , mais le 0x30000 donne une erreur de syntax. si je le met entre ", j'ai une erreur de flag 'code10). Grrrr |
| |
| |
| | | |
|
| | |
| |
Posté le 31 mai 2010 - 09:56 |
et dans le code de Dominique , et nHmi représente quoi comme variable ? |
| |
| |
| | | |
|
| | |
| |
Posté le 31 mai 2010 - 11:05 |
bonjour, il manque des infos dans le code publié de Dominique :
par exemple pmic et pmoc (qui ne sont pas dans un bateau) ne sont pas définis. je soupçonne qu'ils soient des structures midi in et midi out. Il faudrait avoir le code complet de Dominique.
Ami calmant, J.P |
| |
| |
| | | |
|
| | |
| |
Posté le 31 mai 2010 - 13:44 |
a premiere vue , pmic (et pmoc) sont des variables a structure MIDIINCAPSA. D'après les Refs MSDN ça serait logique. Par contre , le nombre de device récupéré par midiInGetNumDevs et null chez moi, et je ne vois pas comment atteindre un autre résultat. ce qui fait que le reste ne passe pas puisque pas de device pour le programme. Ce qui est étonnant , c'est qu'un prog style midi-ox le trouve bien et reçoit les infos |
| |
| |
| | | |
|
| | |
| |
Posté le 31 mai 2010 - 17:27 |
bon, pouwr l'instant, j'ai bien mon périf, il est vu via midiInGetNumDevs, J'ai un retour de midiGetDevCapsA et le midiInopen fonctionne, par contre , j'ai tjrs pas trouvé la valeur de nHmi qui me permettrait de démarrer midiInStart .
J'ai essayé nHmi est un entier système= &sHmi , mais ça ne donne rien Si Dominique regarde de temps à autre ce Post , ça serait cool qu'il me donne les définitions de ses valeurs comme ça , si ça fonctionne , je pourrais l'aiguillé par la suite
Laurent |
| |
| |
| | | |
|
| | |
| |
Posté le 31 mai 2010 - 20:00 |
bon ben moi j'ai finalement trouvé un PC avec une interface midi j'arrive jusqu'à l'ouverture du port midi mais là je coince sur la procedure de callback . Quand on ouvre le port midi d'entrée la callback est apparemment appelée et ça crashe. Je vais pas insister car apparemment après ça se complique encore plus. Au fait pourquoi veux-tu utiliser windev pour la gestion Midi ? il existe des librairies dans d'autres langages et qui sont à un stade très avancés. Par exemple j'ai vu un midi toolkit en .net Ami calmant, J.P |
| |
| |
| | | |
|
| | |
| |
Posté le 01 juin 2010 - 01:30 |
J'ai une application audio ou j'aimerai interface un clavier midi type nanoKey de Korg pour controler le Start et stop de chaque player.
l'application de départ est déjà faite et fonctionne correctement. Je ne sais pas comment savoir si le callback est correctement appelé chez moi. je n'ai pas de crash , le résultat du midiInOpen est de 0 , donc ok avec un entier callback qui est défini par "0x30000"
comment as tu mis ton ouverture de callback ?
Laurent |
| |
| |
| | | |
|
| | |
| |
Posté le 01 juin 2010 - 08:54 |
Je vois que ma question initiale a declenché quelques réactions. J'ai crée sous WD une application qui gère, pour un musicien clavier, la gestion complète de ses besoins. Gestion des partitions des morceaux, et via une interface USB/Midi pilotage de la gestion de sons clavier en fonction des morceaux et celle de l'éclairage par déclenchement associé des scènes programmées dans Daslight. Ces actions sont menées par des commandes midi Out en utilisant plusieurs canaux. Là tout était OK pour moi. Seulement je voulais en plus via une pédale du clavier récuperer sur l'appli des données midi en IN pour gerer par exemple les changements de pages des partitions ou les start/stop de l'éclairage. J'ai calé sur la gestion de l'écoute de canaux midi (IN) et j'ai finalement trouvé une solution bien plus simple par l'utilisation d'une pédale USB en l'associant à un raccourci clavier, lui-même associé à un clic bouton. Premier concert sans lumière déjà fait et avec lumière samedi prochain. Je pourrais certainement revenir sur l'aspect d'écoute de canaux midi en IN car cela peu s'avérer malgré tout utile, en tenant compte de vos remarques. Avec Windev j'ai un peu tendance à développer des trucs perso plutôt en marge. Cela permet de phosphorer un peu. A+ |
| |
| |
| | | |
|
| | |
| |
Posté le 01 juin 2010 - 10:11 |
bonjour, bon ça y est la procédure de callback ne plante plus. Voici le code qui marche chez moi mais attention j'ai pas un USB Midi mais un port Joystick Midi.
MidiINCapsa est une structure wMid est un entier sur 2 octets wPid est un entier sur 2 octets vDriverVersion est un entier szPname est une chaîne ASCIIZ de 32 dwSupport est un entier FIN MidiOUTCapsa est une structure wMid est un entier sur 2 octets wPid est un entier sur 2 octets vDriverVersion est un entier szPname est une chaîne ASCIIZ de 32 wTechnology est un entier sur 2 octets wVoices est un entier sur 2 octets wNotes est un entier sur 2 octets wChannelMask est un entier sur 2 octets dwSupport est un entier FIN retourFonction est un entier
nInd est un entier nNbreOutdevs est un entier nNbreINdevs est un entier pmoc est un tableau de 5 MidiOUTCapsa pmic est un tableau de 5 MidiINCapsa UDeviceID est un entier
hInst est un entier hInst = ChargeDLL("WinMM.DLL") SI hInst = 0 ALORS Erreur(ErreurInfo()) RETOUR FIN nNbreOutdevs =API("WINMM.DLL","midiOutGetNumDevs") nNbreINdevs =API("WINMM.DLL","midiInGetNumDevs") POUR UDeviceID = 1 A nNbreOutdevs retourFonction=API("WINMM.DLL","midiOutGetDevCapsA",UDeviceID-1,&pmoc[UDeviceID],Dimension(pmoc[UDeviceID])) Trace("sortie Midi : " + pmoc[UDeviceID]:wMid + TAB + pmoc[UDeviceID]:wPid + TAB + pmoc[UDeviceID]:szPName)
FIN POUR UDeviceID = 1 A nNbreINdevs retourFonction=API("WINMM.DLL","midiInGetDevCapsA",UDeviceID-1,&pmic[UDeviceID],Dimension(pmic[UDeviceID])) Trace("entrée Midi : " + pmic[UDeviceID]:wMid + TAB + pmic[UDeviceID]:wPid + TAB + pmic[UDeviceID]:szPName) FIN gndeviceIn1 est un entier = 0 nHmi est un entier nGnIDProced est un entier = &MessagemidiIn
retourFonction = API("WINMM.DLL","midiInOpen",&nHmi,gndeviceIn1,nGnIDProced,0,0x30020) Trace("MidiInOpen/" +retourFonction) retourFonction = API("WINMM.DLL","midiInStart",nHmi) Trace("MidiInStart/" +retourFonction)
et voici le code de ma procédure de callback :
Procedure MessagemidiIn( hMidiIn, wMsg, dwInstance, dwParam1, dwParam2)
Trace("on passe ici : " + dwParam1 + TAB + dwParam2 ) Mais attention dans la procédure de callback le plus dur reste à faire : filtrer les événements qui nous interressent. Sinon avec ce code je reçois les évenements envoyés par un clavier Midi.
Ami Calmant, J.P |
| |
| |
| | | |
|
| | |
| |
Posté le 01 juin 2010 - 11:21 |
coool , j'y suis aussi depuis ce matin, je cherche la façon de parser les données du callback
Laurent |
| |
| |
| | | |
|
| | |
| |
Posté le 01 juin 2010 - 11:22 |
fo que je trouve la traduction C vers WD de ceci:
md.mTime = dwParam2; md.mStatus = (UCHAR)(dwParam1 & 0xFF); md.mParam1 = (UCHAR)((dwParam1>> & 0xFF); md.mParam2 = (UCHAR)((dwParam1>>16) & 0xFF);
ce qui permettra de parser le param1 |
| |
| |
| | | |
|
| | |
| |
Posté le 01 juin 2010 - 15:06 |
voici le parsing que j'ai et qui fonctionne comme un charme lol
qui me donne de quoi faire toutes mes opérations sur mon programme depuis mon clavier |
| |
| |
| | | |
|
| | |
| |
Posté le 01 juin 2010 - 16:14 |
je n'ai pas besoin de gestion des channels donc, il n'y a rien pour parser le channel |
| |
| |
| | | |
|
| | |
| |
Posté le 12 mai 2012 - 15:55 |
Bonjour, à vous Je déterre ce post pour la raison suivante
Je suis entrain , tout en me formant à Windev, de réaliser un logiciel de gestion de partitions musicales. J'attaque la partie communication avec un clavier des ports Midi
J'ai essayé les différents portions de code citées dans ce post
Le souci que j'ai c'est les descriptions manquante (les constantes et les variable)
Sans vouloir plagier : y aurait-il un code "complet" que je pourrais adapter ? gestion de sysex à recevoir et a envoyer au clavier entre autre afficher une partition en appuyant sur un bouton du clavier envoyer des réglages au clavier en fonction d'une partition affichée
Un grand merci d'avance pour votre aide
NB je suis en W15 |
| |
| |
| | | |
|
| | |
| |
Posté le 03 novembre 2013 - 09:00 |
je relance les bonnes volontés sur le sujet USB/midi
quelqu'un aurait aurait il un bout de code en windev permettant d'adresser les ports midi via USB, ouverture, fermeture, lecture et écritures pour piloter des périphériques midi (synthé, boite à rythmes.... Yamaha, Rolannd...) une sorte de 'open source" par exemple bien entendu ce que chacun dévelloperait serait mis en commun pour faire progresser le smilblick
chez pcsoft il est impossible d'obtenir des renseignements précis, on reste dans le vague.
je pense que nous sommes nombreux à nous heurter à ce problème
merci aux bonnes volontés |
| |
| |
| | | |
|
| | |
| |
Posté le 03 novembre 2013 - 21:38 |
Bonjour, Voici un morceau de code qui fonctionne pour un changement de banque sons sur un clavier. le code inclus les commandes sur banques à adresses fixes 1 à 127 type KN6000 et à adresses variables x fois 1 à 8 type Tyros4. Les éléments du code utile se situent dans différentes procédures :
Définition stockage mémoire dans la procédure du projet nDwMsg est un entier nHmo est un entier système nHmi est un entier système gnDeviceOut3 est un entier gnCanal est un entier sur 1 gnCodePgm est un entier sur 2 gnCodeBank est un entier sur 2
Init des canaux de communication ( j'ai le clavier et plusieurs canaux pour les lumières) CAS 3 : gnCanalOut3 = T_CanalMidi.CD_OUT // Controle Synthetiseur gnCanalIn3 = T_CanalMidi.CD_IN gnDeviceOut3 = T_CanalMidi.CD_affect_Int gnDeviceIn3 = T_CanalMidi.CD_affect_Int gsLIOption3 = T_CanalMidi.LI_Goupe_Piste
en fin commande de changement de banques // commande Bank et Panel Clavier // Gestion des bank fixes (KN6000) et des bank variables (TYROS4) // Banques Fixes On passe seulement un ordre Changement de programme Valeur midi de 0 à 127) // Banques variables On passe un ordre Controle Change Changement de banque ( puis un ordre changement de programme valeur midi de (0 à 7) // Ouverture Port Clavier retourFonction=API("WINMM.DLL","midiOutOpen",&nHmo,gnDeviceOut3,0,0,0)
gnCanal = gnCanalOut3 gnCodeBank = Val(TABLE_T_Programme_Det.COL_CD_Banque) gnCodePgm = TABLE_T_Programme_Det.COL_Cd_PM_Midi // message = canal bits 1 à 4 // + C(12)*16 bits 5 à 8 C : codification pour action changement de programme B : codification pour action control change // + cdpgm * 256 bits 9 à 12
// passage commande préliminaire changement de banque pour clavier type Tyros4 SI gnCodeGestionMidi = 2 ALORS nDwMsg = gnCanal + 176 + (32*256) + ((gnCodeBank-1)*256*256) retourFonction=API("WINMM.DLL","midiOutShortMsg",nHmo,nDwMsg) FIN nDwMsg = gnCanal + 192 + (gnCodePgm*256) retourFonction=API("WINMM.DLL","midiOutShortMsg",nHmo,nDwMsg)
// Fermeture Port Clavier retourFonction=API("WINMM.DLL","midiOutClose",nHmo)
Quand j'étais dans le flou pour savoir quelles valeurs passer, j'ai utilisé un petit logiciel Miditest.exe bien pratique. En espérant que cela vous aidera. En tout cas mon appli en épate quelque uns. Car ma femme tout en jouant peinard qui gère lumières de la scène et les lumières de la piste de danse c'est sympa. Amicalement. Dominique |
| |
| |
| | | |
|
| | |
| |
Posté le 28 février 2015 - 09:15 |
Bonjour, Je reviens sur le sujet j'ai finalisé mon logiciel de gestion de partitions musicales.Il me manque toujours le traitement des données Midi pour un clavier TYROS (3 4 et 5) Je souhaites en fonction d'une partition donnée enregistrer les registrations créées afin de pouvoir les restituer lors de l'affichage de la partition En sachant que le Tyros est connecté en USB
J'ai une partition affichée dans le logiciel Je crée des registrations sur le Tyros que je sauvegarde Je voudrais que ces informations soient aussi enregistrées dans mon fichier des partitions pour pouvoir réinjecter ça dans le clavier et ainsi récupérer ces registration et eventuellement l'inverse une registration sur le TYROS appelle la partition correspondante
Je donnerai mon logiciel à la personne qui me filera un coup de main (avec le source si elle le souhaite)
Merci d'avance |
| |
| |
| | | |
|
| | |
| |
Posté le 28 février 2015 - 17:54 |
Bonjour, J'ai crée une application pour épouse qui utilise actuellement un Tyros 4. Avant elle avait un KN6000. Cette application est unique et complète car non seulement elle gère l'activation des registrations enregistré, selon que la mémoire du clavier soit de type variable (Tyros4) ou fixe (KN6000) mais aussi des paramètres sur une table de mixage numérique, des programmes de lumières en commandant Daslight ouvert sur le même PC et contient un petit développement de type "DJ" avec pilotage de l'éclairage aussi. Les morceaux sont enregistrés avec des partitions éventuellement multi-pages le déroulé des pages étant en paramétrage libre pour chaque morceau et le changement de page étant fait par une touche raccourci, qui peut être associée à une pédale USB (ce qui plus pratique). Le problème est que je fonctionnement entièrement en midi pour toute ses fonctionnalités avec une interface USB/Midi à 4 entrée et sortie midi Prodipe. Je n'ai pas étudié comment passer les infos par connexion USB directe. Je vais me pencher aussi sur la question. |
| |
| |
| | | |
|
| | |
| |
Posté le 01 mars 2015 - 14:47 |
Bonjour Dominique,
Je te remercie de te pencher sur le sujet, En effet mon appli gère surtout des partitions musicales
Je sais faire jouer des notes au clavier mais ce qui serait intéressant pour moi c'est de récupérer les infos MIDI émises par le tyros lors de l'exécution d'un registre car je suppose que dans un fichier RGT ce sont des infos midi qui sont stockées ? Il suffirait donc de les réinjecter dans le tyros pour simuler le choix d'une registration Ma partition sachant ou est stocké le fichier rgt correspondant sur le disque du tyros
Donc mon souci : Lire le contenu d'un RGT et l'injecter dans le Tyros ou d'un fichier STYLE |
| |
| |
| | | |
|
| | |
| |
Posté le 27 juin 2015 - 18:35 |
Bonjour Dominique,
Cette application est unique et complète car non seulement elle gère l'activation des registrations enregistré, selon que la mémoire du clavier soit de type variable (Tyros4) ou fixe (KN6000) -- C'est cette partie que je voudrais intégrer dans mon logiciel ----
je fonctionnement entièrement en midi pour toute ses fonctionnalités avec une interface USB/Midi à 4 entrée et sortie midi Prodipe. --- J'ai vu le prix d'une interface Prodipe , ce n'est pas trop honéreux donc je pourrais intégrer ça comme contrainte si on veux utiliser l'option activation registre depuis partition. ----
Serais-tu d'accord de me passer le code qui gère cette partie, car malgré mes recherches je suis bloqué,
Je peux te passer une version de mon logiciel si tu le souhaites
Merci d'avance |
| |
| |
| | | |
|
| | |
| |
Posté le 29 juin 2015 - 20:34 |
Bonjour, Je peux te passer le code sans soucis, mais sur la réponse de 11/2013 j'avais mis l'essentiel, mais il vrai que pour des raisons un peu obscures j'ai géré le IN/OUT de l'interface de manière indirecte, avec 4 ensembles de paramètres (gnDeviceOut3 par exemple) mais qui ne correspondent spécialement au IN/OUT de l'interface. C'est une table (T_Canalmidi) qui donne le N° de IN/Out de l'interface. Si gnDeviceOut3 = 3 les signaux midi seront envoyés via la OUT3 de l'interface. Avec une seule série de paramètres cela marchera aussi bien. Si tu mets 1 dans un "gnDeviceOut" tu activeras la sortie OUT1 de l'interface , 2 la sortie OUT2 ... etc.
Sur l'interface midi prodipe 4In/Out il y a un paramétrage qui permet plusieurs mode IN/Out dont 1 standard avec indépendance complète. Je fonctionne dans cette configuration (par exemple pour commander Daslight via un flux mon appli envoi un code via l'USB sur le port 1 il sort donc en OUT1 sur l'interface. Pour activer Daslight qui tourne sur le même PC j'ai simplement branché le cable midi sortant du OUT1 sur le IN1. Pour le clavier j'utilise la sortie OUT3 donc gnDeviceOut3 = 3 En recopiant le bout de code de mon post du 3/11 tu devrais y arrivé sans problème. Pour ne pas avoir de problème de saturation de la mémoire de l'interface il faut à chaque ouvrir le port puis le fermer après envoi du message. Dans mon post toutes ces opération sont notées. Attention aussi pour les canaux, j'ai noté que sur certains appareils il faut "ajuster le canal" on envoie par exemple canal 3 il reçoit la valeur 4. Si on a paramétré sur appareil canal 3 cela ne marche pas. Il faut donc envoyer canal 3-1. Pour des infos plus détaillées, si nécessaire, il faudrait peut-être passer par un canal plus direct de communication. Pour ton logiciel ... il peut être intéressant, mais mon épouse ne fonctionne pas vraiment avec des partitions et un rythme pré programmé. Ils sont 3 dont un batteur. |
| |
| |
| | | |
|
| | |
| |
Posté le 30 juin 2015 - 11:59 |
Bonjour Dominique,
Merci pour tes infos complémentaires,
Je vais essayer ,
Pour le code je veux bien, car sans tout utiliser le code , la lecture du code écrit par un développeur permet toujours de progresser , dans la façon d'écrire et dans les techniques.J'ai constaté ça au cours de mes 40 ans d'informatique !
Je te transmettrai le mien également via dropBox ou équivalent, tu trouveras peut-être quelques trucs intéressants. Je m'engage bien sûr à ne pas diffuser tes sources. Pour une communication en plus direct je ne sais pas trop comment faire , je ne sais pas si on peut mettre une adresse mail dans les posts.
En tout cas merci. |
| |
| |
| | | |
|
| | |
| |
Posté le 30 juin 2015 - 19:06 |
Contactes-te moi sur ma messagerie d.h.durand@orange.fr. |
| |
| |
| | | |
|
| | |
| |
Posté le 11 septembre 2015 - 20:22 |
Bonjour,
Pour compléter le sujet , j'ai maintenant un code qui fonctionne bien
Procedure ChargeInfosMidiOUT(gnCanalOut,gnBanque,gnBankRGT,gnNumPrg)
nCONTROL_CHANGE_INIT= CONTROL_CHANGE * 256 SAI_ResCCInit = CONTROL_CHANGE * 256 SAI_HexaCCInit = EntierVersHexa(SAI_ResCCInit,2)
nPROGRAM_CHANGE_CANAL = PROGRAM_CHANGE + gnCanalOut*256 SAI_ResCanal = PROGRAM_CHANGE + gnCanalOut*256 SAI_PrgCanal = EntierVersHexa(SAI_ResCanal,2)
nPROGRAM_CHANGE_BANQUE= CONTROL_CHANGE + (BANK_CHANGE*256)+ ((gnBanque) * 256*256) SAI_ResCC_CB = CONTROL_CHANGE + (BANK_CHANGE*256)+ ((gnBanque) * 256*256) SAI_ControlChange = EntierVersHexa(SAI_ResCC_CB,2)
nCONTROLCHANGE_CHANGEPROG_RGT= CONTROL_CHANGE + (BANK_CHANGE*256) + ((gnBankRGT) * 256*256) SAI_ResChBank = CONTROL_CHANGE + (BANK_CHANGE*256) + ((gnBankRGT) * 256*256) SAI_ChangeBank = EntierVersHexa(SAI_ResChBank,2) SAI_NumBanque = gnBankRGT SAI_RGT= gnBankRGT
nPROGRAM_CHANGE_PRG= PROGRAM_CHANGE + (gnNumPrg - 1)*256 SAI_ResChRgt = PROGRAM_CHANGE + (gnNumPrg - 1)*256 SAI_ChangeRgt = EntierVersHexa(SAI_ResChRgt,2) SAI_NumRgt = gnNumPrg - 1 SAI_RGT_Prg = gnNumPrg - 1
Procedure ChargeRegistrationSurClavier()
RGT_OuvreMidiOUT() RGT_ActiveCanalOUT() Sleep(100) RGT_ChangeBanque() Sleep(100) RGT_ChangeRegistration() Sleep(100) RGT_ChangeProgramme() Sleep(100) RGT_FermeMidiOut()
Procedure RGT_OuvreMidiOUT()
sMesAff est une chaîne sMesAff = "Port MIDI: " + gnDeviceOut + " Canal: " +gnCanalOut InitCodesRetourFonctionsMIDI() gnRetmidiOutOpen= API("WINMM.DLL","midiOutOpen",&gnHMidi,gnDeviceOut,0,0,0)
Procedure RGT_ActiveCanalOUT()
gnRetCC= API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResCCInit)
SAI_RetCC = gnRetCC SI SAI_RetCC <> 0 ALORS SAI_RetCC..Couleur = RougeFoncé SINON SAI_RetCC..Couleur = VertFoncé FIN
gnRetChangeCanal= API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResCanal)
SAI_RetChoixCanal = gnRetChangeCanal SI SAI_RetChoixCanal <> 0 ALORS SAI_RetChoixCanal..Couleur = RougeFoncé SINON SAI_RetChoixCanal..Couleur = VertFoncé FIN
Procedure RGT_ChangeBanque()
gnRetChangeBank= API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResChBank) SAI_RetControleChange = gnRetChangeBank SI SAI_RetControleChange <> 0 ALORS SAI_RetControleChange..Couleur = RougeFoncé SINON SAI_RetControleChange..Couleur = VertFoncé FIN
Procedure RGT_ChangeRegistration()
gnRetChangeRGT = API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResChRgt)
SAI_RetChangeBank= gnRetChangeRGT SI SAI_RetChangeBank <> 0 ALORS SAI_RetChangeBank..Couleur = RougeFoncé SINON SAI_RetChangeBank..Couleur = VertFoncé FIN
Procedure RGT_ChangeProgramme()
gnRetChangePrg = API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResChRgt)
SAI_RetChangeRGT = gnRetChangePrg SI SAI_RetChangeRGT <> 0 ALORS SAI_RetChangeRGT..Couleur = RougeFoncé SINON SAI_RetChangeRGT..Couleur = VertFoncé FIN
Procedure RGT_FermeMidiOut()
gnRetmidiOutClose= API("WINMM.DLL","midiOutClose",gnHMidi)
SAI_RetmidiOutClose = gnRetmidiOutClose SI SAI_RetmidiOutClose <> 0 ALORS SAI_RetmidiOutClose..Couleur = RougeFoncé SINON SAI_RetmidiOutClose..Couleur = VertFoncé FIN
Maintenant je voudrais traiter la partie Midi IN : Recevoir un code Sysex en provenance du clavier (Un Numero de partition) envoyé lorsque j'apuie sur une touche registration (Qui contient un sysex)
voici les procédures que j'ai : Je ne sais pas comment décoder ce que je reçois, dans toutes ces infos il faudrait que je trouve une info du type F0 05 01 02 03 04 F7 <-- Numéro d'une partition que je vois bien passer dans MidiOX
Procedure MidiIN_Start(nDevice est un entier)
RetFonc est un entier RetFoncStart est un entier nCbmh est un entier sans signe nRetFoncBuff est un entier nGnIDProced est un entier système = &MidiInCalBak
BTN_CaptureMidi..Visible = Faux ListeMidiIN..Visible = Faux
RetFonc = API("WINMM.DLL","midiInOpen",&ri,nDevice, &MidiInCalBak,0,CALLBACK_FUNCTION) RetFoncStart = API("WINMM.DLL","midiInStart",ri)
LIB_Message..Libellé = "Sysex -> J'attend le sysex..."
Procedure MidiInCalBak( nHMidiIn est entier, nWMsg est entier, nDwInstance est entier, dwParam1 est entier système, nDwparam2 est entier)
ValeurRetour est entier mimdata est une chaîne sMsg est une chaîne sParam2Hexa est une chaîne sByte0, sByte1, sByte2, sByte3 sont des chaînes
SAI_nHMidiIn = nHMidiIn SAI_nWMsg = nWMsg
SAI_nDwInstance = nDwInstance
SAI_dwParam1= dwParam1 SAI_dwParam2= nDwparam2
gnInfoCallBack1= dwParam1 gnParam2CallBack= nDwparam2 gnNUMsg= nWMsg gnInstance= nDwInstance
SELON nWMsg CAS MM_MIM_OPEN LIB_Message= "MidiIn Open"
CAS MM_MIM_CLOSE
CAS MM_MIM_DATA LIB_Message = "DATA RECEIVED"
IF dwParam1 > 0 ALORS sMsg = Gauche(Droite("00000000" + DecToHexa(dwParam1), 8), 6) gnInfoCallBack1= dwParam1 gnInfoCallBackHexa = sMsg
sByte3 = Milieu(gnInfoCallBackHexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN sByte2 = Milieu(gnInfoCallBackHexa, 5, 2) sByte1 = Milieu(gnInfoCallBackHexa, 3, 2) sByte0 = Milieu(gnInfoCallBackHexa, 1, 2) mimdata = sByte0 + " - " + sByte1 + " - "+sByte2+ " - "+ sByte3 sMsg = dwParam1 MidiInDemo.Text1= sMsg MidiInDemo.Text2= mimdata SAI_Param1Hexa = mimdata END
sParam2Hexa = Gauche(Droite("00000000" + DecToHexa(nDwparam2),8), 8)
sByte3 = Milieu(sParam2Hexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN
sByte2 = Milieu(sParam2Hexa, 5, 2) sByte1 = Milieu(sParam2Hexa, 3, 2) sByte0 = Milieu(sParam2Hexa, 1, 2) mimdata = sByte0 + " - " + sByte1 + " - "+sByte2+ " - "+ sByte3 SAI_Param2Hexa = mimdata
CAS MM_MIM_LONGDATA LIB_Message = "LONG DATA RECEIVED" CAS MM_MIM_ERROR LIB_Message = "ERROR" CAS MM_MIM_LONGERROR LIB_Message = "LONGERROR" AUTRE CAS FIN
SI dwParam1 > 255 ALORS
gnInfoCallBackHexa = Gauche(Droite("00000000" + DecToHexa(dwParam1), 8), 6) SAI_Param1Hexa = gnInfoCallBackHexa
sByte3 = Milieu(gnInfoCallBackHexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN
sByte2 = Milieu(gnInfoCallBackHexa, 5, 2) sByte1 = Milieu(gnInfoCallBackHexa, 3, 2) sByte0 = Milieu(gnInfoCallBackHexa, 1, 2) mimdata = sByte0 + " " + sByte1 + " "+sByte2+ " "+ sByte3 sMsg = dwParam1 MidiInDemo.Text1= sMsg MidiInDemo.Text2= mimdata
gnNoteJouée= Gauche(Val(gnInfoCallBackHexa,"x"), 2) MidiInDemo.Text4= gnNoteJouée SINON gnInfoCallBackHexa = Gauche(Droite("00000000" + DecToHexa(dwParam1), 8), 6)
sByte3 = Milieu(gnInfoCallBackHexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN
sByte2 = Milieu(gnInfoCallBackHexa, 5, 2) sByte1 = Milieu(gnInfoCallBackHexa, 3, 2) sByte0 = Milieu(gnInfoCallBackHexa, 1, 2) mimdata = sByte0 + " - " + sByte1 + " - "+sByte2+ " - "+ sByte3 MidiInDemo.Text1B = mimdata FIN
Procedure StopCapture()
nRetFonc est un entier
nRetFonc = API("WINMM.DLL","midiInReset",ri) nRetFonc= API("WINMM.DLL","midiInStop",ri) nRetFonc= API("WINMM.DLL","midiInClose",ri)
Je vais bien dans la CALLBACK mais ???????????? Il doit y avoir un filtre à mettre 0xF9 , FILTER_ACTIVE_SENSE (0xFE) et FILTER_CLOCK (0xF8) J'ai vu ça dans des procédures en VB qui urtilisais l'OCX Mabry
Si quelqu'un peut avancer le schmilblic ça serait sympa
Merci d'avance |
| |
| |
| | | |
|
| | |
| |
Posté le 11 septembre 2015 - 20:22 |
Bonjour,
Pour compléter le sujet , j'ai maintenant un code qui fonctionne bien
Procedure ChargeInfosMidiOUT(gnCanalOut,gnBanque,gnBankRGT,gnNumPrg)
nCONTROL_CHANGE_INIT= CONTROL_CHANGE * 256 SAI_ResCCInit = CONTROL_CHANGE * 256 SAI_HexaCCInit = EntierVersHexa(SAI_ResCCInit,2)
nPROGRAM_CHANGE_CANAL = PROGRAM_CHANGE + gnCanalOut*256 SAI_ResCanal = PROGRAM_CHANGE + gnCanalOut*256 SAI_PrgCanal = EntierVersHexa(SAI_ResCanal,2)
nPROGRAM_CHANGE_BANQUE= CONTROL_CHANGE + (BANK_CHANGE*256)+ ((gnBanque) * 256*256) SAI_ResCC_CB = CONTROL_CHANGE + (BANK_CHANGE*256)+ ((gnBanque) * 256*256) SAI_ControlChange = EntierVersHexa(SAI_ResCC_CB,2)
nCONTROLCHANGE_CHANGEPROG_RGT= CONTROL_CHANGE + (BANK_CHANGE*256) + ((gnBankRGT) * 256*256) SAI_ResChBank = CONTROL_CHANGE + (BANK_CHANGE*256) + ((gnBankRGT) * 256*256) SAI_ChangeBank = EntierVersHexa(SAI_ResChBank,2) SAI_NumBanque = gnBankRGT SAI_RGT= gnBankRGT
nPROGRAM_CHANGE_PRG= PROGRAM_CHANGE + (gnNumPrg - 1)*256 SAI_ResChRgt = PROGRAM_CHANGE + (gnNumPrg - 1)*256 SAI_ChangeRgt = EntierVersHexa(SAI_ResChRgt,2) SAI_NumRgt = gnNumPrg - 1 SAI_RGT_Prg = gnNumPrg - 1
Procedure ChargeRegistrationSurClavier()
RGT_OuvreMidiOUT() RGT_ActiveCanalOUT() Sleep(100) RGT_ChangeBanque() Sleep(100) RGT_ChangeRegistration() Sleep(100) RGT_ChangeProgramme() Sleep(100) RGT_FermeMidiOut()
Procedure RGT_OuvreMidiOUT()
sMesAff est une chaîne sMesAff = "Port MIDI: " + gnDeviceOut + " Canal: " +gnCanalOut InitCodesRetourFonctionsMIDI() gnRetmidiOutOpen= API("WINMM.DLL","midiOutOpen",&gnHMidi,gnDeviceOut,0,0,0)
Procedure RGT_ActiveCanalOUT()
gnRetCC= API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResCCInit)
SAI_RetCC = gnRetCC SI SAI_RetCC <> 0 ALORS SAI_RetCC..Couleur = RougeFoncé SINON SAI_RetCC..Couleur = VertFoncé FIN
gnRetChangeCanal= API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResCanal)
SAI_RetChoixCanal = gnRetChangeCanal SI SAI_RetChoixCanal <> 0 ALORS SAI_RetChoixCanal..Couleur = RougeFoncé SINON SAI_RetChoixCanal..Couleur = VertFoncé FIN
Procedure RGT_ChangeBanque()
gnRetChangeBank= API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResChBank) SAI_RetControleChange = gnRetChangeBank SI SAI_RetControleChange <> 0 ALORS SAI_RetControleChange..Couleur = RougeFoncé SINON SAI_RetControleChange..Couleur = VertFoncé FIN
Procedure RGT_ChangeRegistration()
gnRetChangeRGT = API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResChRgt)
SAI_RetChangeBank= gnRetChangeRGT SI SAI_RetChangeBank <> 0 ALORS SAI_RetChangeBank..Couleur = RougeFoncé SINON SAI_RetChangeBank..Couleur = VertFoncé FIN
Procedure RGT_ChangeProgramme()
gnRetChangePrg = API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResChRgt)
SAI_RetChangeRGT = gnRetChangePrg SI SAI_RetChangeRGT <> 0 ALORS SAI_RetChangeRGT..Couleur = RougeFoncé SINON SAI_RetChangeRGT..Couleur = VertFoncé FIN
Procedure RGT_FermeMidiOut()
gnRetmidiOutClose= API("WINMM.DLL","midiOutClose",gnHMidi)
SAI_RetmidiOutClose = gnRetmidiOutClose SI SAI_RetmidiOutClose <> 0 ALORS SAI_RetmidiOutClose..Couleur = RougeFoncé SINON SAI_RetmidiOutClose..Couleur = VertFoncé FIN
Maintenant je voudrais traiter la partie Midi IN : Recevoir un code Sysex en provenance du clavier (Un Numero de partition) envoyé lorsque j'apuie sur une touche registration (Qui contient un sysex)
voici les procédures que j'ai : Je ne sais pas comment décoder ce que je reçois, dans toutes ces infos il faudrait que je trouve une info du type F0 05 01 02 03 04 F7 <-- Numéro d'une partition que je vois bien passer dans MidiOX
Procedure MidiIN_Start(nDevice est un entier)
RetFonc est un entier RetFoncStart est un entier nCbmh est un entier sans signe nRetFoncBuff est un entier nGnIDProced est un entier système = &MidiInCalBak
BTN_CaptureMidi..Visible = Faux ListeMidiIN..Visible = Faux
RetFonc = API("WINMM.DLL","midiInOpen",&ri,nDevice, &MidiInCalBak,0,CALLBACK_FUNCTION) RetFoncStart = API("WINMM.DLL","midiInStart",ri)
LIB_Message..Libellé = "Sysex -> J'attend le sysex..."
Procedure MidiInCalBak( nHMidiIn est entier, nWMsg est entier, nDwInstance est entier, dwParam1 est entier système, nDwparam2 est entier)
ValeurRetour est entier mimdata est une chaîne sMsg est une chaîne sParam2Hexa est une chaîne sByte0, sByte1, sByte2, sByte3 sont des chaînes
SAI_nHMidiIn = nHMidiIn SAI_nWMsg = nWMsg
SAI_nDwInstance = nDwInstance
SAI_dwParam1= dwParam1 SAI_dwParam2= nDwparam2
gnInfoCallBack1= dwParam1 gnParam2CallBack= nDwparam2 gnNUMsg= nWMsg gnInstance= nDwInstance
SELON nWMsg CAS MM_MIM_OPEN LIB_Message= "MidiIn Open"
CAS MM_MIM_CLOSE
CAS MM_MIM_DATA LIB_Message = "DATA RECEIVED"
IF dwParam1 > 0 ALORS sMsg = Gauche(Droite("00000000" + DecToHexa(dwParam1), 8), 6) gnInfoCallBack1= dwParam1 gnInfoCallBackHexa = sMsg
sByte3 = Milieu(gnInfoCallBackHexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN sByte2 = Milieu(gnInfoCallBackHexa, 5, 2) sByte1 = Milieu(gnInfoCallBackHexa, 3, 2) sByte0 = Milieu(gnInfoCallBackHexa, 1, 2) mimdata = sByte0 + " - " + sByte1 + " - "+sByte2+ " - "+ sByte3 sMsg = dwParam1 MidiInDemo.Text1= sMsg MidiInDemo.Text2= mimdata SAI_Param1Hexa = mimdata END
sParam2Hexa = Gauche(Droite("00000000" + DecToHexa(nDwparam2),8), 8)
sByte3 = Milieu(sParam2Hexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN
sByte2 = Milieu(sParam2Hexa, 5, 2) sByte1 = Milieu(sParam2Hexa, 3, 2) sByte0 = Milieu(sParam2Hexa, 1, 2) mimdata = sByte0 + " - " + sByte1 + " - "+sByte2+ " - "+ sByte3 SAI_Param2Hexa = mimdata
CAS MM_MIM_LONGDATA LIB_Message = "LONG DATA RECEIVED" CAS MM_MIM_ERROR LIB_Message = "ERROR" CAS MM_MIM_LONGERROR LIB_Message = "LONGERROR" AUTRE CAS FIN
SI dwParam1 > 255 ALORS
gnInfoCallBackHexa = Gauche(Droite("00000000" + DecToHexa(dwParam1), 8), 6) SAI_Param1Hexa = gnInfoCallBackHexa
sByte3 = Milieu(gnInfoCallBackHexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN
sByte2 = Milieu(gnInfoCallBackHexa, 5, 2) sByte1 = Milieu(gnInfoCallBackHexa, 3, 2) sByte0 = Milieu(gnInfoCallBackHexa, 1, 2) mimdata = sByte0 + " " + sByte1 + " "+sByte2+ " "+ sByte3 sMsg = dwParam1 MidiInDemo.Text1= sMsg MidiInDemo.Text2= mimdata
gnNoteJouée= Gauche(Val(gnInfoCallBackHexa,"x"), 2) MidiInDemo.Text4= gnNoteJouée SINON gnInfoCallBackHexa = Gauche(Droite("00000000" + DecToHexa(dwParam1), 8), 6)
sByte3 = Milieu(gnInfoCallBackHexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN
sByte2 = Milieu(gnInfoCallBackHexa, 5, 2) sByte1 = Milieu(gnInfoCallBackHexa, 3, 2) sByte0 = Milieu(gnInfoCallBackHexa, 1, 2) mimdata = sByte0 + " - " + sByte1 + " - "+sByte2+ " - "+ sByte3 MidiInDemo.Text1B = mimdata FIN
Procedure StopCapture()
nRetFonc est un entier
nRetFonc = API("WINMM.DLL","midiInReset",ri) nRetFonc= API("WINMM.DLL","midiInStop",ri) nRetFonc= API("WINMM.DLL","midiInClose",ri)
Je vais bien dans la CALLBACK mais ???????????? Il doit y avoir un filtre à mettre 0xF9 , FILTER_ACTIVE_SENSE (0xFE) et FILTER_CLOCK (0xF8) J'ai vu ça dans des procédures en VB qui urtilisais l'OCX Mabry
Si quelqu'un peut avancer le schmilblic ça serait sympa
Merci d'avance |
| |
| |
| | | |
|
| | |
| |
Posté le 11 septembre 2015 - 20:22 |
Bonjour,
Pour compléter le sujet , j'ai maintenant un code qui fonctionne bien
Procedure ChargeInfosMidiOUT(gnCanalOut,gnBanque,gnBankRGT,gnNumPrg)
nCONTROL_CHANGE_INIT= CONTROL_CHANGE * 256 SAI_ResCCInit = CONTROL_CHANGE * 256 SAI_HexaCCInit = EntierVersHexa(SAI_ResCCInit,2)
nPROGRAM_CHANGE_CANAL = PROGRAM_CHANGE + gnCanalOut*256 SAI_ResCanal = PROGRAM_CHANGE + gnCanalOut*256 SAI_PrgCanal = EntierVersHexa(SAI_ResCanal,2)
nPROGRAM_CHANGE_BANQUE= CONTROL_CHANGE + (BANK_CHANGE*256)+ ((gnBanque) * 256*256) SAI_ResCC_CB = CONTROL_CHANGE + (BANK_CHANGE*256)+ ((gnBanque) * 256*256) SAI_ControlChange = EntierVersHexa(SAI_ResCC_CB,2)
nCONTROLCHANGE_CHANGEPROG_RGT= CONTROL_CHANGE + (BANK_CHANGE*256) + ((gnBankRGT) * 256*256) SAI_ResChBank = CONTROL_CHANGE + (BANK_CHANGE*256) + ((gnBankRGT) * 256*256) SAI_ChangeBank = EntierVersHexa(SAI_ResChBank,2) SAI_NumBanque = gnBankRGT SAI_RGT= gnBankRGT
nPROGRAM_CHANGE_PRG= PROGRAM_CHANGE + (gnNumPrg - 1)*256 SAI_ResChRgt = PROGRAM_CHANGE + (gnNumPrg - 1)*256 SAI_ChangeRgt = EntierVersHexa(SAI_ResChRgt,2) SAI_NumRgt = gnNumPrg - 1 SAI_RGT_Prg = gnNumPrg - 1
Procedure ChargeRegistrationSurClavier()
RGT_OuvreMidiOUT() RGT_ActiveCanalOUT() Sleep(100) RGT_ChangeBanque() Sleep(100) RGT_ChangeRegistration() Sleep(100) RGT_ChangeProgramme() Sleep(100) RGT_FermeMidiOut()
Procedure RGT_OuvreMidiOUT()
sMesAff est une chaîne sMesAff = "Port MIDI: " + gnDeviceOut + " Canal: " +gnCanalOut InitCodesRetourFonctionsMIDI() gnRetmidiOutOpen= API("WINMM.DLL","midiOutOpen",&gnHMidi,gnDeviceOut,0,0,0)
Procedure RGT_ActiveCanalOUT()
gnRetCC= API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResCCInit)
SAI_RetCC = gnRetCC SI SAI_RetCC <> 0 ALORS SAI_RetCC..Couleur = RougeFoncé SINON SAI_RetCC..Couleur = VertFoncé FIN
gnRetChangeCanal= API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResCanal)
SAI_RetChoixCanal = gnRetChangeCanal SI SAI_RetChoixCanal <> 0 ALORS SAI_RetChoixCanal..Couleur = RougeFoncé SINON SAI_RetChoixCanal..Couleur = VertFoncé FIN
Procedure RGT_ChangeBanque()
gnRetChangeBank= API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResChBank) SAI_RetControleChange = gnRetChangeBank SI SAI_RetControleChange <> 0 ALORS SAI_RetControleChange..Couleur = RougeFoncé SINON SAI_RetControleChange..Couleur = VertFoncé FIN
Procedure RGT_ChangeRegistration()
gnRetChangeRGT = API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResChRgt)
SAI_RetChangeBank= gnRetChangeRGT SI SAI_RetChangeBank <> 0 ALORS SAI_RetChangeBank..Couleur = RougeFoncé SINON SAI_RetChangeBank..Couleur = VertFoncé FIN
Procedure RGT_ChangeProgramme()
gnRetChangePrg = API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResChRgt)
SAI_RetChangeRGT = gnRetChangePrg SI SAI_RetChangeRGT <> 0 ALORS SAI_RetChangeRGT..Couleur = RougeFoncé SINON SAI_RetChangeRGT..Couleur = VertFoncé FIN
Procedure RGT_FermeMidiOut()
gnRetmidiOutClose= API("WINMM.DLL","midiOutClose",gnHMidi)
SAI_RetmidiOutClose = gnRetmidiOutClose SI SAI_RetmidiOutClose <> 0 ALORS SAI_RetmidiOutClose..Couleur = RougeFoncé SINON SAI_RetmidiOutClose..Couleur = VertFoncé FIN
Maintenant je voudrais traiter la partie Midi IN : Recevoir un code Sysex en provenance du clavier (Un Numero de partition) envoyé lorsque j'apuie sur une touche registration (Qui contient un sysex)
voici les procédures que j'ai : Je ne sais pas comment décoder ce que je reçois, dans toutes ces infos il faudrait que je trouve une info du type F0 05 01 02 03 04 F7 <-- Numéro d'une partition que je vois bien passer dans MidiOX
Procedure MidiIN_Start(nDevice est un entier)
RetFonc est un entier RetFoncStart est un entier nCbmh est un entier sans signe nRetFoncBuff est un entier nGnIDProced est un entier système = &MidiInCalBak
BTN_CaptureMidi..Visible = Faux ListeMidiIN..Visible = Faux
RetFonc = API("WINMM.DLL","midiInOpen",&ri,nDevice, &MidiInCalBak,0,CALLBACK_FUNCTION) RetFoncStart = API("WINMM.DLL","midiInStart",ri)
LIB_Message..Libellé = "Sysex -> J'attend le sysex..."
Procedure MidiInCalBak( nHMidiIn est entier, nWMsg est entier, nDwInstance est entier, dwParam1 est entier système, nDwparam2 est entier)
ValeurRetour est entier mimdata est une chaîne sMsg est une chaîne sParam2Hexa est une chaîne sByte0, sByte1, sByte2, sByte3 sont des chaînes
SAI_nHMidiIn = nHMidiIn SAI_nWMsg = nWMsg
SAI_nDwInstance = nDwInstance
SAI_dwParam1= dwParam1 SAI_dwParam2= nDwparam2
gnInfoCallBack1= dwParam1 gnParam2CallBack= nDwparam2 gnNUMsg= nWMsg gnInstance= nDwInstance
SELON nWMsg CAS MM_MIM_OPEN LIB_Message= "MidiIn Open"
CAS MM_MIM_CLOSE
CAS MM_MIM_DATA LIB_Message = "DATA RECEIVED"
IF dwParam1 > 0 ALORS sMsg = Gauche(Droite("00000000" + DecToHexa(dwParam1), 8), 6) gnInfoCallBack1= dwParam1 gnInfoCallBackHexa = sMsg
sByte3 = Milieu(gnInfoCallBackHexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN sByte2 = Milieu(gnInfoCallBackHexa, 5, 2) sByte1 = Milieu(gnInfoCallBackHexa, 3, 2) sByte0 = Milieu(gnInfoCallBackHexa, 1, 2) mimdata = sByte0 + " - " + sByte1 + " - "+sByte2+ " - "+ sByte3 sMsg = dwParam1 MidiInDemo.Text1= sMsg MidiInDemo.Text2= mimdata SAI_Param1Hexa = mimdata END
sParam2Hexa = Gauche(Droite("00000000" + DecToHexa(nDwparam2),8), 8)
sByte3 = Milieu(sParam2Hexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN
sByte2 = Milieu(sParam2Hexa, 5, 2) sByte1 = Milieu(sParam2Hexa, 3, 2) sByte0 = Milieu(sParam2Hexa, 1, 2) mimdata = sByte0 + " - " + sByte1 + " - "+sByte2+ " - "+ sByte3 SAI_Param2Hexa = mimdata
CAS MM_MIM_LONGDATA LIB_Message = "LONG DATA RECEIVED" CAS MM_MIM_ERROR LIB_Message = "ERROR" CAS MM_MIM_LONGERROR LIB_Message = "LONGERROR" AUTRE CAS FIN
SI dwParam1 > 255 ALORS
gnInfoCallBackHexa = Gauche(Droite("00000000" + DecToHexa(dwParam1), 8), 6) SAI_Param1Hexa = gnInfoCallBackHexa
sByte3 = Milieu(gnInfoCallBackHexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN
sByte2 = Milieu(gnInfoCallBackHexa, 5, 2) sByte1 = Milieu(gnInfoCallBackHexa, 3, 2) sByte0 = Milieu(gnInfoCallBackHexa, 1, 2) mimdata = sByte0 + " " + sByte1 + " "+sByte2+ " "+ sByte3 sMsg = dwParam1 MidiInDemo.Text1= sMsg MidiInDemo.Text2= mimdata
gnNoteJouée= Gauche(Val(gnInfoCallBackHexa,"x"), 2) MidiInDemo.Text4= gnNoteJouée SINON gnInfoCallBackHexa = Gauche(Droite("00000000" + DecToHexa(dwParam1), 8), 6)
sByte3 = Milieu(gnInfoCallBackHexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN
sByte2 = Milieu(gnInfoCallBackHexa, 5, 2) sByte1 = Milieu(gnInfoCallBackHexa, 3, 2) sByte0 = Milieu(gnInfoCallBackHexa, 1, 2) mimdata = sByte0 + " - " + sByte1 + " - "+sByte2+ " - "+ sByte3 MidiInDemo.Text1B = mimdata FIN
Procedure StopCapture()
nRetFonc est un entier
nRetFonc = API("WINMM.DLL","midiInReset",ri) nRetFonc= API("WINMM.DLL","midiInStop",ri) nRetFonc= API("WINMM.DLL","midiInClose",ri)
Je vais bien dans la CALLBACK mais ???????????? Il doit y avoir un filtre à mettre 0xF9 , FILTER_ACTIVE_SENSE (0xFE) et FILTER_CLOCK (0xF8) J'ai vu ça dans des procédures en VB qui urtilisais l'OCX Mabry
Si quelqu'un peut avancer le schmilblic ça serait sympa
Merci d'avance |
| |
| |
| | | |
|
| | |
| |
Posté le 11 septembre 2015 - 20:23 |
Bonjour,
Pour compléter le sujet , j'ai maintenant un code qui fonctionne bien
Procedure ChargeInfosMidiOUT(gnCanalOut,gnBanque,gnBankRGT,gnNumPrg)
nCONTROL_CHANGE_INIT= CONTROL_CHANGE * 256 SAI_ResCCInit = CONTROL_CHANGE * 256 SAI_HexaCCInit = EntierVersHexa(SAI_ResCCInit,2)
nPROGRAM_CHANGE_CANAL = PROGRAM_CHANGE + gnCanalOut*256 SAI_ResCanal = PROGRAM_CHANGE + gnCanalOut*256 SAI_PrgCanal = EntierVersHexa(SAI_ResCanal,2)
nPROGRAM_CHANGE_BANQUE= CONTROL_CHANGE + (BANK_CHANGE*256)+ ((gnBanque) * 256*256) SAI_ResCC_CB = CONTROL_CHANGE + (BANK_CHANGE*256)+ ((gnBanque) * 256*256) SAI_ControlChange = EntierVersHexa(SAI_ResCC_CB,2)
nCONTROLCHANGE_CHANGEPROG_RGT= CONTROL_CHANGE + (BANK_CHANGE*256) + ((gnBankRGT) * 256*256) SAI_ResChBank = CONTROL_CHANGE + (BANK_CHANGE*256) + ((gnBankRGT) * 256*256) SAI_ChangeBank = EntierVersHexa(SAI_ResChBank,2) SAI_NumBanque = gnBankRGT SAI_RGT= gnBankRGT
nPROGRAM_CHANGE_PRG= PROGRAM_CHANGE + (gnNumPrg - 1)*256 SAI_ResChRgt = PROGRAM_CHANGE + (gnNumPrg - 1)*256 SAI_ChangeRgt = EntierVersHexa(SAI_ResChRgt,2) SAI_NumRgt = gnNumPrg - 1 SAI_RGT_Prg = gnNumPrg - 1
Procedure ChargeRegistrationSurClavier()
RGT_OuvreMidiOUT() RGT_ActiveCanalOUT() Sleep(100) RGT_ChangeBanque() Sleep(100) RGT_ChangeRegistration() Sleep(100) RGT_ChangeProgramme() Sleep(100) RGT_FermeMidiOut()
Procedure RGT_OuvreMidiOUT()
sMesAff est une chaîne sMesAff = "Port MIDI: " + gnDeviceOut + " Canal: " +gnCanalOut InitCodesRetourFonctionsMIDI() gnRetmidiOutOpen= API("WINMM.DLL","midiOutOpen",&gnHMidi,gnDeviceOut,0,0,0)
Procedure RGT_ActiveCanalOUT()
gnRetCC= API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResCCInit)
SAI_RetCC = gnRetCC SI SAI_RetCC <> 0 ALORS SAI_RetCC..Couleur = RougeFoncé SINON SAI_RetCC..Couleur = VertFoncé FIN
gnRetChangeCanal= API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResCanal)
SAI_RetChoixCanal = gnRetChangeCanal SI SAI_RetChoixCanal <> 0 ALORS SAI_RetChoixCanal..Couleur = RougeFoncé SINON SAI_RetChoixCanal..Couleur = VertFoncé FIN
Procedure RGT_ChangeBanque()
gnRetChangeBank= API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResChBank) SAI_RetControleChange = gnRetChangeBank SI SAI_RetControleChange <> 0 ALORS SAI_RetControleChange..Couleur = RougeFoncé SINON SAI_RetControleChange..Couleur = VertFoncé FIN
Procedure RGT_ChangeRegistration()
gnRetChangeRGT = API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResChRgt)
SAI_RetChangeBank= gnRetChangeRGT SI SAI_RetChangeBank <> 0 ALORS SAI_RetChangeBank..Couleur = RougeFoncé SINON SAI_RetChangeBank..Couleur = VertFoncé FIN
Procedure RGT_ChangeProgramme()
gnRetChangePrg = API("WINMM.DLL","midiOutShortMsg",gnHMidi,SAI_ResChRgt)
SAI_RetChangeRGT = gnRetChangePrg SI SAI_RetChangeRGT <> 0 ALORS SAI_RetChangeRGT..Couleur = RougeFoncé SINON SAI_RetChangeRGT..Couleur = VertFoncé FIN
Procedure RGT_FermeMidiOut()
gnRetmidiOutClose= API("WINMM.DLL","midiOutClose",gnHMidi)
SAI_RetmidiOutClose = gnRetmidiOutClose SI SAI_RetmidiOutClose <> 0 ALORS SAI_RetmidiOutClose..Couleur = RougeFoncé SINON SAI_RetmidiOutClose..Couleur = VertFoncé FIN
Maintenant je voudrais traiter la partie Midi IN : Recevoir un code Sysex en provenance du clavier (Un Numero de partition) envoyé lorsque j'apuie sur une touche registration (Qui contient un sysex)
voici les procédures que j'ai : Je ne sais pas comment décoder ce que je reçois, dans toutes ces infos il faudrait que je trouve une info du type F0 05 01 02 03 04 F7 <-- Numéro d'une partition que je vois bien passer dans MidiOX
Procedure MidiIN_Start(nDevice est un entier)
RetFonc est un entier RetFoncStart est un entier nCbmh est un entier sans signe nRetFoncBuff est un entier nGnIDProced est un entier système = &MidiInCalBak
BTN_CaptureMidi..Visible = Faux ListeMidiIN..Visible = Faux
RetFonc = API("WINMM.DLL","midiInOpen",&ri,nDevice, &MidiInCalBak,0,CALLBACK_FUNCTION) RetFoncStart = API("WINMM.DLL","midiInStart",ri)
LIB_Message..Libellé = "Sysex -> J'attend le sysex..."
Procedure MidiInCalBak( nHMidiIn est entier, nWMsg est entier, nDwInstance est entier, dwParam1 est entier système, nDwparam2 est entier)
ValeurRetour est entier mimdata est une chaîne sMsg est une chaîne sParam2Hexa est une chaîne sByte0, sByte1, sByte2, sByte3 sont des chaînes
SAI_nHMidiIn = nHMidiIn SAI_nWMsg = nWMsg
SAI_nDwInstance = nDwInstance
SAI_dwParam1= dwParam1 SAI_dwParam2= nDwparam2
gnInfoCallBack1= dwParam1 gnParam2CallBack= nDwparam2 gnNUMsg= nWMsg gnInstance= nDwInstance
SELON nWMsg CAS MM_MIM_OPEN LIB_Message= "MidiIn Open"
CAS MM_MIM_CLOSE
CAS MM_MIM_DATA LIB_Message = "DATA RECEIVED"
IF dwParam1 > 0 ALORS sMsg = Gauche(Droite("00000000" + DecToHexa(dwParam1), 8), 6) gnInfoCallBack1= dwParam1 gnInfoCallBackHexa = sMsg
sByte3 = Milieu(gnInfoCallBackHexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN sByte2 = Milieu(gnInfoCallBackHexa, 5, 2) sByte1 = Milieu(gnInfoCallBackHexa, 3, 2) sByte0 = Milieu(gnInfoCallBackHexa, 1, 2) mimdata = sByte0 + " - " + sByte1 + " - "+sByte2+ " - "+ sByte3 sMsg = dwParam1 MidiInDemo.Text1= sMsg MidiInDemo.Text2= mimdata SAI_Param1Hexa = mimdata END
sParam2Hexa = Gauche(Droite("00000000" + DecToHexa(nDwparam2),8), 8)
sByte3 = Milieu(sParam2Hexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN
sByte2 = Milieu(sParam2Hexa, 5, 2) sByte1 = Milieu(sParam2Hexa, 3, 2) sByte0 = Milieu(sParam2Hexa, 1, 2) mimdata = sByte0 + " - " + sByte1 + " - "+sByte2+ " - "+ sByte3 SAI_Param2Hexa = mimdata
CAS MM_MIM_LONGDATA LIB_Message = "LONG DATA RECEIVED" CAS MM_MIM_ERROR LIB_Message = "ERROR" CAS MM_MIM_LONGERROR LIB_Message = "LONGERROR" AUTRE CAS FIN
SI dwParam1 > 255 ALORS
gnInfoCallBackHexa = Gauche(Droite("00000000" + DecToHexa(dwParam1), 8), 6) SAI_Param1Hexa = gnInfoCallBackHexa
sByte3 = Milieu(gnInfoCallBackHexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN
sByte2 = Milieu(gnInfoCallBackHexa, 5, 2) sByte1 = Milieu(gnInfoCallBackHexa, 3, 2) sByte0 = Milieu(gnInfoCallBackHexa, 1, 2) mimdata = sByte0 + " " + sByte1 + " "+sByte2+ " "+ sByte3 sMsg = dwParam1 MidiInDemo.Text1= sMsg MidiInDemo.Text2= mimdata
gnNoteJouée= Gauche(Val(gnInfoCallBackHexa,"x"), 2) MidiInDemo.Text4= gnNoteJouée SINON gnInfoCallBackHexa = Gauche(Droite("00000000" + DecToHexa(dwParam1), 8), 6)
sByte3 = Milieu(gnInfoCallBackHexa, 7, 2) SI sByte3 = "" ALORS sByte3 = "00" FIN
sByte2 = Milieu(gnInfoCallBackHexa, 5, 2) sByte1 = Milieu(gnInfoCallBackHexa, 3, 2) sByte0 = Milieu(gnInfoCallBackHexa, 1, 2) mimdata = sByte0 + " - " + sByte1 + " - "+sByte2+ " - "+ sByte3 MidiInDemo.Text1B = mimdata FIN
Procedure StopCapture()
nRetFonc est un entier
nRetFonc = API("WINMM.DLL","midiInReset",ri) nRetFonc= API("WINMM.DLL","midiInStop",ri) nRetFonc= API("WINMM.DLL","midiInClose",ri)
Je vais bien dans la CALLBACK mais ???????????? Il doit y avoir un filtre à mettre 0xF9 , FILTER_ACTIVE_SENSE (0xFE) et FILTER_CLOCK (0xF8) J'ai vu ça dans des procédures en VB qui urtilisais l'OCX Mabry
Si quelqu'un peut avancer le schmilblic ça serait sympa
Merci d'avance |
| |
| |
| | | |
|
| | |
| |
Posté le 21 novembre 2015 - 07:24 |
Jurassic Pork a écrit :
Salut Laurent, MidiInProc n'est pas une fonction qu'on peut appeler par la dll. Par contre j'ai vu une erreur dans le code de Dominique : retourFonction = API("WINMM.DLL","midiInOpen",&nHmi,gnDeviceIn1,gnIDProced,0,0) le dernier paramètre est à zéro (dwflags) ce qui fait qu'on appelle la fonction avec un CALLBACK_NULL il n'y aura pas de mécanisme de callback donc pas d'exécution de la procédure MessagemidiIn. Il faut appeler la dll avec comme dernier paramètre CALLBACK_FUNCTION qui a pour valeur 0x30000 donc cela donne : retourFonction =API("WINMM.DLL","midiInOpen",&nHmi,gnDeviceIn1,gnIDProced,0,0x30000) je te garantis pas que ça va marcher mais tu peux toujours essayer. Moi je n'ai pas d'interface midi donc je peux pas essayer. Ami calmant, J.P |
| |
| |
| | | |
|
| | |
| |
Posté le 23 novembre 2015 - 13:34 |
Bonjour, Je reviens sur le sujet MIDIIn : Procédure CallBack
Je suis toujours à la recherche d'un bout de code qui permet de décortiquer les contenus de Param1 et param2
Dans MIDIOx je vois passer l'info que je dois récupérer c'est une infosysex du Type F0 05 01 02 03 04 F7 et je veux récupérer 1234 qui est le n° d'une partition
Merci aux spécialistes MIDI et WINDEV |
| |
| |
| | | |
|
| | |
| |
Posté le 27 juin 2016 - 10:59 |
Bonjour tout le monde, Je revient sur le sujet "Envoi de messages sur le Midi OUT
Je cherche a envoyer un sysex vers un clavier Yamaha (Tyros 5) - pour faire monter un style avec le code suivant
sSysexEnvoi est une chaîne = TABLE_StylesTyros5.COL_Sysex[TABLE_StylesTyros5]
nLongueur est un int = Dimension(sSysexEnvoi) tabByteArray est un tableau de nLongueur entier sur 1
K est un int
FOR K = 1 TO nLongueur tabByteArray[K] = Asc(Milieu(sSysexEnvoi, K, 1)) END
nCodeSysex est un entier = TABLE_StylesTyros5.COL_CodeStyle[TABLE_StylesTyros5] sYMH_MSG est une chaîne nResultat,nResultat1,nResultat2 est un entier
STMIDIHDR est une structure DataPtr est une chaîne BufferLength est un entier sur 8 BytesRecorded est un entier sur 8 MhdrID est un entier sur 8 Flags est un entier sur 8 lpNext est un entier sur 8 Reserved2 est un entier sur 8 CallbackOffset est un entier Reserved3a est un entier sur 8 octets Reserved3b est un entier sur 8 octets Reserved3c est un entier sur 8 octets Reserved3d est un entier sur 8 octets FIN
MidiInHdr est un tableau fixe de NumSysexBuffers STMIDIHDR
hMidiIn est un entier stHdr est un STMIDIHDR nSize est un entier = Taille(sSysexEnvoi) nCONTROL_CHANGE_INIT = CONTROL_CHANGE * 256 nPROGRAM_CHANGE_CANAL = PROGRAM_CHANGE + gnCanalOut*256 gnRetmidiOutOpen = API("WINMM.DLL","midiOutOpen",&gnHMidi,gnDeviceOut,0,0,0) gnRetCC = API("WINMM.DLL","midiOutShortMsg",gnHMidi,nCONTROL_CHANGE_INIT) gnRetChangeCanal = API("WINMM.DLL","midiOutShortMsg",gnHMidi,nPROGRAM_CHANGE_CANAL) stHdr.BufferLength = nSize stHdr.BytesRecorded = nSize stHdr.DataPtr = &tabByteArray nResultat = API("WINMM.DLL","midiOutPrepareHeader",gnHMidi,&stHdr,nSize) SI nResultat <> 0 ALORS AfficheErreurMidiOUT(nResultat) FIN nResultat1 = API("WINMM.DLL","midiOutLongMsg",gnHMidi,&stHdr,nSize) Sleep(50) SI nResultat1 <> 0 ALORS AfficheErreurMidiOUT(nResultat1) FIN nResultat2 = API("WINMM.DLL","midiOutUnprepareHeader",gnHMidi,&stHdr,nSize) SI nResultat2 <> 0 ALORS AfficheErreurMidiOUT(nResultat2) FIN gnRetmidiOutClose = API("WINMM.DLL","midiOutClose",gnHMidi)
Tous les codes retour donnent bien 0, mais mon sysex n'est pas pris en compte. D'après ce que j'ai pu voir dans certains programmes en VB le sysex doit être transformé en Byte sur 2 octets.
Ce que j'ai trouvé en VB: 'Envoie un message long Public Sub MidiSendLong(ByVal hMidiOut As Integer, ByVal text_msg As String)
Dim hdr As MIDIHDR Dim result As Integer Dim ss() As String = text_msg.Split(" ") Dim size As Integer = ss.Length
hdr.lpData = System.Runtime.InteropServices.Marshal.AllocHGlobal(size) -de la librairie mscorlib For i As Integer = 0 To size - 1 System.Runtime.InteropServices.Marshal.WriteByte(hdr.lpData, i, CByte(Val("&h" & ss(i)))) -de la librairie mscorlib Next hdr.dwBufferLength = size hdr.dwBytesRecorded = size
result = midiOutPrepareHeader(hMidiOut, hdr, 48) result = midiOutLongMsg(hMidiOut, hdr, 48) result = midiOutUnprepareHeader(hMidiOut, hdr, 48)
System.Runtime.InteropServices.Marshal.FreeHGlobal(hdr.lpData)
End Sub
J'en appelle aux spécialistes MIDI/WINDEV pour des conseils éclairés avec mes chaleureux remerciements |
| |
| |
| | | |
|
| | | | |
| | |
|