Bonjour a tous je suis nouveau sur le forum et également débutant avec GTK

j'ai crée un programme en console qui effectue l'acquisition et le traitement de signal après avoir validé son fonctionnement je souhaite mtn realiser une interface graphique simple pour afficher les valeurs .

Donc je n'ai aucun bouton a gérer , juste la "croix" pour quitter , je veux juste faire un calcul , afficher les résultat , faire le calcul , afficher etc tout ca en boucle
j'ai donc regarder des tutos et apres quelques heures j'ai réussi a crée mon interface , ainsi que manipuler les labels pour afficher des valeurs .

J'ai donc décider de réunir mon programme en console et mon interface et la c'est le drame...le programme tourne , mais il bloque l'IHM
j'utilise des "g_timeout_add" pour actualiser mes valeurs et faire mon calcul j'ai entendu parler de g_iddle_add mais je n'ai pas vraiment saisi a quoi il sert...
....j'ai également parler de threads en cherchant et j'avoue que ça me fait peur parce que etant étudiant en électronique généralement les programmes sont séquentiel et assez simple...

je pense que le problèmes c'est que mon acquisition de données et mon calcul ça dure...12 sec et c'est ça qui doit pas trop plaire a GTK..
je pensais qu'en mettant des delais plus court pour l’actualisation des valeurs ça marcherai ...mais non..

avez vous de quoi éclairer ma lanterne ? ou alors répondre a cette question : threads obligatoire ou pas threads? ou encore mieux pour les valeurs ne s'actualise pas ?

je vous remercie

mon code :
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
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <time.h>
#include <alsa/asoundlib.h>
#include <math.h>
#include <stdbool.h> 
#include "mailbox.h" 
#include "gpu_fft.h"
#define NUM_COMMANDS   7  // nombre de commande gnuplot ( tracé du spectre )
////////////////////////////////////////////Prototype///////////////////////////////////////////////////////////////////////////////////////////////
void SpectreIMG(void); 
int fft_compute_forward(float * input, int log2_N, float * output, double sampling_interval);
/////////////////////////////////////////////Variables ///////////////////////////////////////////////////////////////////////////////////////////////
snd_pcm_t *capture_handle;
snd_pcm_hw_params_t *hw_params;
snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE; // format des variables de la carte son
 
unsigned int rate = 44100;// frequence echantillonage
int NLOG2 = 19;//taille de notre FFT ici 2^15 = 32768 point 
int buffer_frames =524288; // nombre de frames ( nombre de mesure par periode )
unsigned long N ;//nombre de point FFT
double freqmin;// frequence min de la "zone" du spectre a analyser
double freqmax;// frequence max de zone
double  resolution ;
double Rmin ;
double Rmax ; 
int raiMin ;
int raiMax ;
int i,j;
int err;
int16_t *buffer; // buffer integer 16bits
float* float_buffer; // buffer de float
double vitesse ;
double Pmeca ;
double rendement;
double Pelec ;
char* devcID;// Identifiant carte son /* paraetres de manipulation ALSA */
float *OutData2; 
float *OutData;//buffer de sortie FFT
double multiplier  ;
int Peaki;// determiner la valeur crete
float PeakValue;//amplitude de la valeur crete
float frequence ;
bool init = false ;
 
/////////////////////////////////////////////////////////////////////Fin Variables///////////////////////////////////////////////////////////////////////////////
 
int fft_compute_forward(float * input, int log2_N, float * output, double sampling_interval)
{
   int mb = mbox_open();
   int jobs = 1, i;
   unsigned long N = 1 << log2_N;
   float FloatN = (float)N;
   float HalfN = FloatN / 2.0;
   struct GPU_FFT_COMPLEX * base;
   struct GPU_FFT * fft;
   struct GPU_FFT_COMPLEX *DataIn, *DataOut;
   int ret = gpu_fft_prepare(mb, log2_N, GPU_FFT_FWD, jobs, &fft);
   base = fft->in;
 for (i = 0; i<N; i++)
{
base[i].re = input[i]; base[i].im = 0.0;
}
   gpu_fft_execute(fft);
   base = fft->out;
for (i = 0; i<N; i++)
{
output[i] = (base[i].re * base[i].re) + (base[i].im * base[i].im);
}
gpu_fft_release(fft);
mbox_close(mb);
}
 
 
void Process1(char * devcID) {  //cette fonction prepare la carte son et alloue la memoire pour acceuillir les données de sortie de la FFT
 
 
 
 /**************************Ouverture du device en mode capture(enregistrement)******************/
if ((err = snd_pcm_open(&capture_handle, devcID, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
fprintf(stderr, "impossible d'ouvrir le device %s (%s)\n",devcID,snd_strerror(err));
exit(1);
} else {fprintf(stdout, "device ouvert avec succes\n");}
 /*************************Ajout de la structure parametres************************************/
if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
fprintf(stderr, "impossible d'ajouter les parametres (%s)\n",snd_strerror(err));
exit(1);
}   else { fprintf(stdout, "parametres ajouter\n"); }
if ((err = snd_pcm_hw_params_any(capture_handle, hw_params)) < 0) {
fprintf(stderr, "impossible d'initialiser les parametres (%s)\n",snd_strerror(err));
exit(1);
}   else { fprintf(stdout, "parametres initialise\n"); }
/**********************************Configuration type d'acces *******************************************************/
if ((err = snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
fprintf(stderr, "impossible de conigurer le type d'acces (%s)\n",snd_strerror(err));
exit(1);
}   else { fprintf(stdout, "type dacces configure!\n"); }
/********************************Format de donne********************************************************************/
if ((err = snd_pcm_hw_params_set_format(capture_handle, hw_params, format)) < 0) {
 fprintf(stderr, "impossible de parametrer le format (%s)\n",snd_strerror(err));
exit(1);
}   else { fprintf(stdout, "format regle\n"); }
/********************************************Réglage frequence echantillonage*****************************************************/
 if ((err = snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &rate, 0)) < 0) {
 fprintf(stderr, "impossible de regler la frequence d'echantillonage (%s)\n",snd_strerror(err));
exit(1);
}   else { fprintf(stdout, "frequence d'echantillonage réglee\n"); }
/*************************************************Reglage nombre de chaines (Mono ou stereo)**********************************/
if ((err = snd_pcm_hw_params_set_channels(capture_handle, hw_params, 1)) < 0) {
printf(stderr, "impossible de regler le nombre de chaine (%s)\n",snd_strerror(err));
exit(1);
}   else { fprintf(stdout, "nombre de chaine regle\n"); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if ((err = snd_pcm_hw_params(capture_handle, hw_params)) < 0) {
fprintf(stderr, "impossible d'appliquer les parametres (%s)\n",snd_strerror(err));
exit(1);
}   else { fprintf(stdout, "Applications des parametres\n"); }
snd_pcm_hw_params_free(hw_params);// nettoyage de la strucure de prametres
fprintf(stdout, "parametres efface\n"); /************************************************************Preparation de la carte son pour la 
capture***************************************/
if ((err = snd_pcm_prepare(capture_handle)) < 0) {
 fprintf(stderr, "impossible de preparer la carte pour enregistrement (%s)\n",snd_strerror(err));
 exit(1);}   else { fprintf(stdout, "pret a enregistrer \n"); }
 }
 
gboolean Process2(gpointer data)
{
 
/*if ((err = snd_pcm_pause(capture_handle,0)) < 0) {
 fprintf(stderr, "impossible de resume la carte",snd_strerror(err));
 exit(1);}   else { fprintf(stdout,"carte resume done \n"); } */
 
 
//lecture et stockage dans le buffer des données de la carte son
if ((err = snd_pcm_readi(capture_handle, buffer, buffer_frames)) != buffer_frames) {
fprintf(stderr, "erreur de lecture interface audio (%s)\n",err, snd_strerror(err));
exit(1);
}
 
 
 
 
//cast des interger16 en float en vue d'une FFT prochaine
for (i = 0; i < buffer_frames; i++){
float_buffer[i] = (float)buffer[i];
}
 
 
//fenetre de hamming ----------->https://fr.wikipedia.org/wiki/Fen%C3%AAtrage
for (i=0; i < buffer_frames; i++){
multiplier = 0.54-0.46*cos(2*M_PI*i/(buffer_frames-1));
float_buffer[i] = multiplier * float_buffer[i]; // les données sont multplier par un coefficient
}
 
printf("CALCUL FFT GPU \n ");
fft_compute_forward(float_buffer, NLOG2, OutData, 1);
usleep(100);
for (i = 0 ; i < (N/2); i++){
OutData2[(i)] = OutData[i] ;  // supression de -Fe/2
}
// trouver le pic dans la FFT
Peaki=0;
PeakValue=0;
for(i= raiMin;i<= raiMax;i++)
{
if(OutData2[i] > PeakValue)
 {
PeakValue= OutData2[i];
Peaki = i;
frequence =((float)Peaki*(((float)rate)/((double)N)));
}
}
vitesse = frequence*60.0 ;
 
 printf("Localisation d'un Pic a la raie numero %d  Amplitude = %.0f\n\n", Peaki,PeakValue);
printf("la fréquence identifie est : %6.4f   \n" ,frequence);
printf("la vitesse est :  %f  \n" ,vitesse);
 
return TRUE ;
 
 
}
 
void quit(void)
{
 free(buffer);
 free(OutData);
free(OutData2);
fprintf(stdout, "memory nettoye\n");
snd_pcm_close(capture_handle);
fprintf(stdout, "fermeture interface audio............OK\n");
gtk_main_quit();
 
 
}
 
gboolean update(gpointer data)
{
    GtkWidget *label5 = data;
    // time_t result = time(NULL);
    gchar *str;
     str = g_strdup_printf ("%f",Pelec);
 
    gtk_label_set_text(GTK_LABEL(label5),str);
 
   return TRUE;
} 
 
gboolean update1(gpointer data)
{
    GtkWidget *label6 = data;
  //   time_t result = time(NULL);
     gchar *str;
     str = g_strdup_printf ("%f",vitesse);
 
    gtk_label_set_text(GTK_LABEL(label6),str);
 
   return TRUE;
}
 
gboolean update2(gpointer data)
{
    GtkWidget *label7 = data;
     //time_t result = time(NULL);
     gchar *str;
     str = g_strdup_printf ("%f",rendement);
 
    gtk_label_set_text(GTK_LABEL(label7),str);
 
   return TRUE;
}
 
gboolean update3(gpointer data)
{
    GtkWidget *label8 = data;
//     time_t result = time(NULL);
     gchar *str;
     str = g_strdup_printf ("%f",frequence);
 
    gtk_label_set_text(GTK_LABEL(label8),str);
 
   return TRUE;
}
 
 
 
 
int main (int argc, char *argv[]){
 
 devcID = malloc(sizeof(char) * 5); // allocation de mémoire de taille 5 char pour passer le device en argument au lancement du programme
if (argc > 1){
devcID = argv[1];  // on recupere le numero de carte son a utiliser dans l'argument 1
freqmin  =  atof(argv[2]); // on recupere la frequence min de  limite zone
freqmax  =  atof(argv[3]);// on recupere la frequence max de limite zone
 }
else {
      devcID = "hw:0,0"; // si il n'ya aucun argument on prend l'interface par default
   }
 
N = 1 << NLOG2;  // on calcul le nombre de point de la FFT
resolution = (double)rate/(double)N ;// on calcul la resoltion de la FFT
 
Rmin = freqmin/resolution ; // on calcul le numero de raie qui correspond a la frequence min
Rmax = freqmax/resolution ;//on calcul le numero de raie qui correspond a la frequence max
raiMin = (int)Rmin-1;// on cast  le numero de raie pour passer  entier puis on prend la valeur en dessous pour etre sur d'etre dans la fentre 
raiMax = (int)Rmax+1;//  on cast  le numero de raie pour passer  entier puis on prend la valeur en dessous pour etre sur d'etre dans la fentre
printf("%f \n",freqmin);//affichage de toute les variables ( debugage )
printf("%f \n",freqmax);
printf("%d \n", rate);
printf("%d \n", N);
printf("%f \n",resolution);
printf("%f \n",Rmin);
printf("%f \n",Rmax);
printf("%d \n",raiMin);
printf("%d \n",raiMax);
fprintf(stdout, "raiMin : %d  raiMax : %d  resolution: %f  \n",raiMin,raiMax,resolution);
Process1(devcID);// on prepare la carte son
 // allocation de suffisament de memoire pour enregistrement 128*16 /8 * 2
buffer = malloc(buffer_frames * snd_pcm_format_width(format) / 8 * 2);
float_buffer = malloc(buffer_frames*sizeof(float));
fprintf(stdout, "memoire alouee!!\n");
OutData = malloc(N * sizeof(float)); //allocation mémoire de notre buffer en fonction du nombre de point FFT
OutData2  =malloc(N/2 * sizeof(float));
//Process2(NULL);
/* free(buffer); 
 free(OutData);
free(OutData2);*/
//fprintf(stdout, "memory nettoye\n");
//snd_pcm_close(capture_handle);
//fprintf(stdout, "fermeture interface audio............OK\n");
 
 
 
int i ;
    GtkWidget *window;
    GtkWidget *zone;
    GtkWidget *label1;  //puissance electrique 
    GtkWidget *label2;  //puissance mecanique
    GtkWidget *label3;  //rendement 
    GtkWidget *label4; //frequence vibration:
    GtkWidget *label5; //Valeur puissance
    GtkWidget *label6; //Valeur Pmeca
    GtkWidget *label7; // rendement valuer
    GtkWidget *label8;  // frequence valeur
  gchar* TexteConverti = NULL;
//   long time = (long)time(NULL); 
// time_t result = time(NULL);
//	gchar *str; 
 
//	str = g_strdup_printf ("%d",result);
    gtk_init (&argc, &argv);
 
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size (GTK_WINDOW (window), 640,480);
 
    zone = gtk_fixed_new ();
 
    /* On ajoute la zone comme conteneur dans la fenêtre */
    gtk_container_add (GTK_CONTAINER (window), zone);
 
 
   TexteConverti = g_locale_to_utf8("<span face=\"Verdana\" foreground=\"#73b5ff\" size=\"xx-large\"><b>Puissance Electrique :</b></span>\n", -1, NULL, NULL, NULL);
    label1 = gtk_label_new (TexteConverti);
    TexteConverti = g_locale_to_utf8("<span face=\"Verdana\" foreground=\"#73b5ff\" size=\"xx-large\"><b>Puissance Mecanique :</b></span>\n", -1, NULL, NULL, NULL);
    label2 = gtk_label_new(TexteConverti);
    TexteConverti = g_locale_to_utf8("<span face=\"Verdana\" foreground=\"#73b5ff\" size=\"xx-large\"><b>Rendement:</b></span>\n", -1, NULL, NULL, NULL);
    label3 = gtk_label_new(TexteConverti);
    TexteConverti = g_locale_to_utf8("<span face=\"Verdana\" foreground=\"#73b5ff\" size=\"xx-large\"><b>Frequence vibration :</b></span>\n", -1, NULL, NULL, NULL);
    label4 = gtk_label_new(TexteConverti);
    label5 = gtk_label_new("valeur");
    label6 = gtk_label_new("valeurMeca");
    label7 = gtk_label_new("rendement");
    label8 = gtk_label_new("frequence");
 gtk_label_set_use_markup(GTK_LABEL(label1), TRUE); // On dit que l'on utilise les balises pango
 gtk_label_set_use_markup(GTK_LABEL(label2), TRUE); // On dit que l'on utilise les balises pango
 gtk_label_set_use_markup(GTK_LABEL(label3), TRUE); // On dit que l'on utilise les balises pango
 gtk_label_set_use_markup(GTK_LABEL(label4), TRUE); // On dit que l'on utilise les balises pango
// gtk_label_set_use_markup(GTK_LABEL(label5), TRUE); // On dit que l'on utilise les balises pango
    /* On ajoute le bouton dans la zone à la position 100;100 */
 
    gtk_fixed_put (GTK_FIXED (zone), label1,40,40);
    gtk_fixed_put (GTK_FIXED (zone), label2,40,100);
    gtk_fixed_put (GTK_FIXED (zone), label3,40,160);
    gtk_fixed_put (GTK_FIXED (zone), label4,40,220);
    gtk_fixed_put(GTK_FIXED (zone), label5,450,40);
    gtk_fixed_put(GTK_FIXED (zone), label6,450,100);
    gtk_fixed_put(GTK_FIXED (zone), label7,450,160);
    gtk_fixed_put(GTK_FIXED (zone), label8,450,220); 
   // gtk_label_set_text ((GtkLabel*)label5, str);
 
 
//        g_free (str);
// connection des signaux evenmentiel 
    g_signal_connect (G_OBJECT (window), "destroy",
                      G_CALLBACK (quit), NULL);
g_timeout_add(10, update,label5);// update label 5 
g_timeout_add(10, update1,label6);// update label 6 
g_timeout_add(10, update2,label7);// update label 7 
g_timeout_add(10, update3,label8);// update label 8
g_timeout_add(1000, Process2,NULL);
gtk_widget_show_all (window);
gtk_main();
 
    return EXIT_SUCCESS;
}
PS : la fonction d'acquisition et de calcul c'est Process2() ;