Bonjour,
J'effectue des captures sysex avec les fonction de Winmm.dll
Dans ces capture je récupere un sysex particulier que j'envoie à mon thread principal qui doit effectuer un traitement sur celui-ci
Mes captures se passent bien - je détectebien mon sysex - le premier traitement s'exécute normalement
Je doit ensuite réinitialiser les tampons MIDIHDR utilisés par MidiInStart et relancer une ecoute pour effectuer une nouvelle capture
J'exécute bien toutes mes procédures y compris le nouveau MidiInstart
Mais mon thread principal reste bloqué
Je pense que je fais une mauvaise utilisation des threads
J'ai fait un trace qui indique les différentes procédures exécutée




TEST CAPTURE MIDI IN
Handle Fenetre Principale = 5247418
----------------------------------------------------------------
--> ON LANCE LA CAPTURE (1èere fois)
1-On lance OuvreMidiIn
OuvreMidiIN Ok pour Handle 7903472
- Le Handle MidiIn est égal à : 7903472
----------------------------------------------
2-On fait UnPrepareHeader sur 600 Buffers
3-On fait PrepareHeader et AddBuffer sur 600 Buffers
4-Relance le Thread EcouteMidiIn1
--> THREAD INACTIF- On fait ThreadExecute pour EcouteMidiIn1()
--> Thread EcouteMidiIn Actif
--> On lance MidiInStart
--> MidiInStart OK sur Handle : 7903472
5-On lance EnclencheRedemarre
- Thread automatique fait avec fonction 1:30
- Teste si on a reçu un N° de partition
- PartitionRecive = 0
001 F0 43 10 4C 08 00 76 04 F7
002 F0 43 10 4C 08 00 72 1E F7
003 F0 43 10 4C 08 00 73 40 F7
004 F0 43 10 4C 08 01 0D 40 F7
005 F0 43 10 4C 08 01 0C 40 F7
006 F0 43 10 4C 08 01 76 04 F7
007 F0 43 10 4C 08 01 72 1E F7
008 F0 43 10 4C 08 01 77 2F F7
009 F0 43 10 4C 08 01 73 40 F7
010 F0 43 10 4C 08 03 1E 40 F7
011 F0 43 10 4C 0A 03 40 0F F7
012 F0 43 10 4C 0A 03 42 4B F7
013 F0 43 10 4C 08 03 0D 46 F7
014 F0 43 10 4C 08 02 1E 40 F7
015 F0 43 10 4C 08 02 76 12 F7
016 F0 43 10 4C 08 02 77 30 F7
017 F0 43 10 4C 03 03 00 15 10 F7
018 F0 43 10 4C 03 03 0C 02 F7
019 F0 43 10 4C 03 03 0B 14 F7
020 F0 43 10 4C 03 04 00 42 11 F7
021 F0 43 10 4C 03 04 02 0A F7
022 F0 43 10 4C 03 04 0B 0A F7
023 F0 43 10 4C 08 08 11 7F F7
024 F0 43 10 4C 08 09 11 7F F7
025 F0 43 10 4C 08 0A 11 7F F7
026 F0 43 10 4C 08 0B 11 7F F7
027 F0 43 10 4C 08 0C 11 7F F7
028 F0 43 10 4C 08 0D 11 7F F7
029 F0 43 10 4C 08 0E 11 7F F7
030 F0 43 10 4C 08 0F 11 7F F7
031 F0 43 7E 00 02 00 F7
032 F0 43 7E 00 08 7F F7
033 F0 43 7E 00 08 00 F7
034 F0 43 7E 00 02 7F F7
035 F0 43 7E 01 00 28 58 2A F7
036 F0 43 7E 01 00 28 58 2A F7
037 F0 43 10 4C 02 01 00 01 20 F7
038 F0 43 10 4C 02 01 20 41 00 F7
039 F0 43 10 4C 02 01 40 15 00 F7
040 F0 43 10 4C 02 01 5A 01 F7
041 F0 43 10 4C 02 01 42 00 08 F7
042 F0 43 10 4C 02 40 01 49 F7
043 F0 43 10 4C 02 40 02 1F F7
044 F0 43 10 4C 02 40 03 14 F7
045 F0 43 10 4C 02 40 05 47 F7
046 F0 43 10 4C 02 40 06 1B F7
047 F0 43 10 4C 02 40 07 0C F7
048 F0 43 10 4C 02 40 09 46 F7
049 F0 43 10 4C 02 40 0A 26 F7
050 F0 43 10 4C 02 40 0B 10 F7
051 F0 43 10 4C 02 40 0D 45 F7
052 F0 43 10 4C 02 40 0E 2A F7
053 F0 43 10 4C 02 40 0F 19 F7
054 F0 43 10 4C 02 40 11 49 F7
055 F0 43 10 4C 02 40 12 36 F7
056 F0 43 10 4C 02 40 13 0A F7
057 F0 43 10 4C 02 01 40 40 00 F7
058 F0 7E 7F 09 01 F7
059 F0 43 10 4C 02 01 00 01 20 F7
060 F0 43 10 4C 02 01 0C 40 F7
061 F0 43 10 4C 02 01 0D 40 F7
062 F0 43 10 4C 02 01 20 41 00 F7
063 F0 43 10 4C 02 01 2D 40 F7
064 F0 43 10 4C 02 01 2E 00 F7
065 F0 00 00 00 00 01 09 F7
065 Partition---------> 19
066 F0 43 10 4C 02 01 40 15 00 F7
067 F0 43 10 4C 02 01 5A 01 F7
068 F0 43 10 4C 02 01 5B 7F F7
069 F0 43 10 4C 02 01 42 00 08 F7
070 F0 43 10 4C 02 01 56 40 F7
071 F0 43 10 4C 02 01 57 40 F7
072 F0 43 10 4C 02 01 58 00 F7
--> EnclencheRedemarre
073 F0 43 10 4C 02 01 59 00 F7
- On Lance la procédure Redemarre
074 F0 43 10 4C 02 01 5C 40 F7
- PartitionRecive = 1
075 F0 43 10 4C 02 01 5D 40 F7
--> Procedure Redemarre :
076 F0 43 10 4C 02 01 5E 40 F7
1-Affichage Parition N° 19
077 F0 43 10 4C 02 01 5F 40 F7
- Envoi d'un PostMessage FinDuSysex sur Handle : 5247418
078 F0 43 10 4C 02 01 60 40 F7
2-On lance MidiInReset sur Handle : 7903472
--> Procédure FinDuSysex (Affiche part N° 19 dans FenetrePrincipale)
079 F0 43 10 4C 08 08 14 00 F7
- Enclenché par un PostMessage
RESET pour Handle 7903472
080 F0 43 10 4C 08 09 14 00 F7
- Partition N° 19
3-On lance MidiInStop sur Handle : 7903472
Stop OK pour Handle 7903472
4-On lance MidiInClose sur Handle : 7903472
MidiInClose OK pour Handle 7903472
5-On lance la procédure LancerCaptureMidiIn()
--> RELANCE CAPTURE (Après affichage d'une partition)
1-On lance OuvreMidiIn
OuvreMidiIN Ok pour Handle 7904264
- Le Handle MidiIn est égal à : 7904264
----------------------------------------------
2-On fait UnPrepareHeader sur 600 Buffers
3-On fait PrepareHeader et AddBuffer sur 600 Buffers
4-Relance le Thread EcouteMidiIn1
--> THREAD INACTIF- On fait ThreadExecute pour EcouteMidiIn1()
--> Thread EcouteMidiIn Actif
--> On lance MidiInStart
--> MidiInStart OK sur Handle : 7904264
5-On lance EnclencheRedemarre
- Thread automatique fait avec fonction 1:30
- Teste si on a reçu un N° de partition
- PartitionRecive = 0

ça reste bloqué à ce niveau là même lorsque j'appuie sur un bouton du synthé qui envoie les sysex

Nb : si je n'exécute pas une réinitialisation, ça fonctionne jusqu'a ce que j'aie atteint mon maxi de buffer (600 dans mon test)
Je pense que c'est donc bien un probleme de relance des threads car je n'ai pas d'erreurs sur Les Close, Reset, stop, Prepareheader, UnprepareHeader,AddBuffer. Mon Tableau de 600 Buffers est bien réinitialisé comme au premier lancement.

Ce que je voudrais faire dans le programme principal pour la capture

BOUCLE
Lancer Capture MidiIN
le programme principal s'exécute normalement et attend en même temps l'envoi de sysex
SI envoi sysex
Recup N+ de partition
Affichage de la partition
Réinitialisation des tampons pour repartir à zéro
Relancer L'écoute
Retour au programme principal qui attend les sysex
FIN
FIN

Merci d'avance pour votre aide


Ci dessous le code Utilisé

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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")