1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
|
ThreadMode(threadSectionCritique)
Trace("TEST CAPTURE MIDI IN")
Trace(" Handle Fenetre Principale = " + HandleFenPrinc)
Trace("----------------------------------------------------------------")
LancerCaptureMidiIn("Premiere")
//---------------------------------------------------------------------------------------------------------------
PROCEDURE LancerCaptureMidiIn(QuelCas)
//---------------------------------------------------------------------------------------------------------------
i est un entier
FEN_PRINCIPALE.BTN_Demarre..Visible = Faux // Pour ne pas ouvrir plusieurs à la fois et ne pas planter
SI QuelCas = "Relance" ALORS
Trace("--> RELANCE CAPTURE (Après affichage d'une partition)")
SINON
Trace("--> ON LANCE LA CAPTURE (1èere fois)")
FIN
Trace(" 1-On lance OuvreMidiIn ")
OuvreMidiIn()
Trace(" 2-On fait UnPrepareHeader sur "+NumSysexBuffers + " Buffers")
POUR i = 1 _A_ NumSysexBuffers
MidiInUnprepareHeader(i)
FIN
Trace(" 3-On fait PrepareHeader et AddBuffer sur "+NumSysexBuffers + " Buffers")
InitialiseBuffers()
//Lancement 1er Thread secondaire
ThreadSysexActif = Faux
Trace(" 4-Relance le Thread EcouteMidiIn1")
SI PAS ThreadSysexActif ALORS
ThreadSysexActif = Vrai
Trace(" --> THREAD INACTIF- On fait ThreadExecute pour EcouteMidiIn1() ")
ThreadExécute(THREADATTENDSYSEX,threadContexteGlobal,EcouteMidiIn1) // EcouteMidiIn lance un 2eme Thread
SINON
Trace(" --> THREAD ACTIF- Est-ce Normal ? ")
FIN
TANTQUE ThreadEtat(THREADATTENDSYSEX) = threadEnCours
SI PartitionSysex <> 0 ALORS
Trace("--> DANS LE THREAD : Partition "+PartitionSysex)
FIN
FIN
Trace(" 5-On lance EnclencheRedemarre")
Trace(" - Thread automatique fait avec fonction 1:30 ")
Trace(" - Teste si on a reçu un N° de partition ")
Trace(" - PartitionRecive = "+PartitionRecive)
EnclencheRedemarre() // C'est un thread fait avec 1:30
//----------------------------------------------------------------------------------------------------
PROCEDURE EcouteMidiIn1()
//----------------------------------------------------------------------------------------------------
SI PAS ThreadSysexActif ALORS
RETOUR
FIN
SI ThreadEtat(THREADATTENDSYSEX) = threadInexistant ALORS
Trace(" --> Thread inactif")
SINON
Trace(" --> Thread " +THREADATTENDSYSEX + " Actif")
FIN
nRetFoncStart est un entier
Trace(" --> On lance MidiInStart")
nRetFoncStart = API("WINMM.DLL","midiInStart",HandleMidiIn) // On démarre l'écoute
SI nRetFoncStart <> 0 ALORS
Trace(" --> MidiINStart Erreur sur Handle :"+HandleMidiIn)
SINON
Trace(" --> MidiInStart OK sur Handle : "+HandleMidiIn)
FIN
//-------------------------------------------------------------------------------------------------------------
PROCEDURE MidiHandlerBack(INMidi est un entier,wMsg est un entier système,dwInstance,dwParam1,DwParam2)
//-------------------------------------------------------------------------------------------------------------
//PROCEDURE MidiHandlerBack( stINMidi est un entier,wMsg est un entier systeme,nsyDwInstance est un entier systeme,dwParam1 est un entier système,DwParam2 est un entier système)
//Parameters
//HMIDIIN hMidiIn,
//UINT wMsg,
//DWORD_PTR dwInstance,
//DWORD_PTR dwParam1,
//DWORD_PTR dwParam2
//hMidiIn : Handle to the MIDI input device.
//wMsg : MIDI input message.
//dwInstance : Instance data supplied with the*midiInOpen*function.
//dwParam1 : Message parameter.
//DwParam2 : Message parameter.
//------------------------------------------
//MM_MIM_LONGDATA
// wParam = (WPARAM) hInput
// lParam = (LPARAM) lpMidiHdr
// Paramètres
// hInput :Manipuler le dispositif d'entrée MIDI qui a reçu les données.
// lpMidiHdr :Pointeur vers une*MIDIHDR*structure de l'*identification de*la mémoire tampon.
//--------------------------------------------------------------------------------------------------------------------------------------
sData est chaînes ASCIIZ de SysExSize
SELON wMsg
CAS MM_MIM_DATA
//m est un tableau de 3 entiers sur 1 octet // en VB -> Dim m(2) As Byte
//b est un entier systeme
//Chan est un entier systeme // Canal midi
//savparam1 est un entier sans signe sur 4 octets
//savparam1 = dwParam1 // pour ne pas détruire wParam dans notre processus
//POUR i = 1 _A_ 3
// b = savparam1 & 0xFF // En VB -> Dim _b As Byte = CByte(wParam2 And &HFF)
// m[i] = b
// savparam1 = bitDécaleDroite(DwParam2,8) // wParam2 >> 8
//FIN
//SELON dwParam1
//CAS 254
//AUTRE CAS
//MIM_DATA_Reception()
CAS MM_MIM_OPEN
CAS MM_MIM_CLOSE
CAS MM_MIM_LONGDATA // 964 ou 0x3C4
SI PAS FlagReset ALORS
SI SysexRecus[MsgNombre].SysExHeader.BytesRecorded <> 0 ALORS
sData = DoSysExData(MsgNombre,dwInstance) // Traiter le sysex
SINON
//EnclencheRedemarre()
Trace("FlagStop = Vrai -----------------------------> -" + FlagStop)
FlagStop = Vrai
//PostMessage(HandleFenPrinc,FIN_TRAITEMENT,MsgNombre,PartitionSysex)
SI FlagReset ALORS
// On ne prend rien
FIN
FIN
SINON
// Pas de données
FIN
MsgNombre++
CAS MM_MIM_ERROR //TODO: handle (message to trigger exception?) };
PostMessage( HandleFenPrinc, WM_MIM_ERROR, dwInstance, dwParam1)
CAS MM_MIM_LONGERROR
PostMessage( HandleFenPrinc, WM_MIM_LONGERROR, dwInstance, dwParam1)
FIN //{ SELON wMsg }
PROCEDURE DoSysExData(NumMsg,aDeviceIndex)
//------------------------------------------------------------------------------------------------------------------------------------
// INFOS SUR LES STRUCTURES UTILISEES
// SysExData est une structure
// NumSysex est un entier
// MsgCode est un entier systeme // Code Msg : 963, 964
// SysExHeader est un MIDIHDR // le MIDIHDR qui entregistre les infos relative au message Midi
// Param1 est un entier sans signe sur 4 octets // dwParam1 recu dans la CallBack
// Param2 est un entier systeme // dwParam2 recu dans la CalBack
// TailleSysex est un entier systeme // = SysExHeader.ByteRecorded
// DataPtr est un entier systeme // = SysExHeader.DataPtr : Pointeur Data du Sysex = normalement doit pointer sur SysexInfo
// SysexInfo est un entier sans signe sur 4 octets // Contenu data de SysExHeader.DataPtr
// Sysexchaine est un tableau de BufferInSize entier sans signe sur 1 octet // Contient la data du pointeur SysExHeader.DataPtr en tableau de n octets
// SysexTraduit est une chaine // contient la chaine sysex finale sous forme F0 43 10 4C 08 00 1E 2A F7
// NumeroPartition est un entier // contiendra le numéro de partition récupéré dans un sysex
//FIN
i,LaPart sont un entiers
LeSysex est une chaîne = ""
LaPart = 0
i = NumMsg
SI SysexRecus[MsgNombre].SysExHeader.BytesRecorded = 0 ALORS
//MsgNombre++
ThreadFin()
RENVOYER LeSysex
SINON
Transfert(&SysexRecus[i].SysexBuffer,SysexRecus[i].SysExHeader.DataPtr,SysexRecus[i].SysExHeader.BytesRecorded) // en VB -> Marshal.Copy(MidiInHdr(i).DataPtr, InSysex, 0, BufferInSize) SysexRecus[nbSysex].SysExHeader &TMidiInHdr[i].DataPtr
SysexRecus[i].DataPtr = SysexRecus[i].SysExHeader.DataPtr
SysexRecus[i].TailleSysex = SysexRecus[i].SysExHeader.BytesRecorded
SysexRecus[i].NumSysex = NumMsg
SysexRecus[i].SysexTraduit = BufferEnHexa(SysexRecus[i].SysexBuffer,SysexRecus[i].SysExHeader.BytesRecorded)
SysexRecus[i].SysExHeader.BytesRecorded = 0
LeSysex = SysexRecus[i].SysexTraduit // La data a été traitée
LaPart = ChercheNumPartDansSysex(LeSysex,"00")
SysexRecus[i].NumeroPartition = LaPart
Trace(NumériqueVersChaîne(MsgNombre,"03d") + " "+ LeSysex)
//ListeAjoute(Liste1,NumériqueVersChaîne(MsgNombre,"03d")+" -> "+LeSysex)
SI LaPart <> 0 ALORS
PartitionSysex = LaPart // On charge l'info a récupérer
Trace(NumériqueVersChaîne(MsgNombre,"03d") + " " + "Partition---------> " + PartitionSysex)
//ListeAjoute(Liste1,NumériqueVersChaîne(MsgNombre,"03d")+" -> "+LeSysex+" --------- Partition N° "+PartitionSysex)
PartitionRecive = Vrai
//PostMessage(HandleFenPrinc,FIN_TRAITEMENT,MsgNombre,LaPart)
FIN
FIN
SI MsgNombre > NumSysexBuffers-1 ALORS
//Il Faut vider les Buffer pour repartir au début
FIN
RENVOYER LeSysex
//--------------------------------------------------------------------// Procédure automatique :
// La procédure est exécutée manuellement, lors d'un appel dans le code
// L'exécution n'aura lieu qu'à la fin de l'évènement contenant l'appel
// Elle s'exécutera dans un thread (sans avoir besoin d'appeler la fonction ThreadExecute), sans utilisation de HFSQL
// Elle sera répétée en boucle, en attendant 1 seconde entre chaque appel
// --------------------------------------------------------------------
PROCEDURE EnclencheRedemarre()
//--------------------------------------------------------------------
SI PartitionRecive ALORS
Trace(" --> EnclencheRedemarre")
Trace(" - On Lance la procédure Redemarre")
Trace(" - PartitionRecive = "+PartitionRecive)
Redemarre()
FIN
//------------------------------------------------------------------------------------------
PROCEDURE Redemarre()
//------------------------------------------------------------------------------------------
FEN_PRINCIPALE.SAI_NoPart = ""
Trace("--> Procedure Redemarre :")
Trace(" 1-Affichage Parition N° "+PartitionSysex)
Trace(" - Envoi d'un PostMessage FinDuSysex sur Handle : "+HandleFenPrinc)
PostMessage(HandleFenPrinc,FIN_TRAITEMENT,MsgNombre,PartitionSysex)
PartitionRecive = Faux
Trace(" 2-On lance MidiInReset sur Handle : "+ HandleMidiIn)
ThreadExécute("ResetIn",threadNormal,ResetMidiIn)
TANTQUE ThreadEtat("ResetIn") = threadEnCours
// Attend fin du reset
FIN
// Stoper Capture
Trace(" 3-On lance MidiInStop sur Handle : "+ HandleMidiIn)
SI PAS StopMidiIn() ALORS
Trace(" --> STOP IN ERREUR sur Handle : "+ HandleMidiIn)
FIN
Trace(" 4-On lance MidiInClose sur Handle : "+ HandleMidiIn)
SI PAS FermeMidiIn() ALORS
Trace(" --> MidiInClose ERREUR sur Handle : "+ HandleMidiIn)
FIN
Trace(" 5-On lance la procédure LancerCaptureMidiIn() ")
LancerCaptureMidiIn("Relance") |
Partager