Bonjour-bonsoir heureux confinés (!...)
Une fois n'est pas coutume : je vais vous soumettre du code. Mais je vais d'abord expliquer ce que je veux faire (attention, ça va décoiffer !).
J'utilise la DLL WINMM pour récupérer le son d'un micro, et je veux afficher le "sonogramme" obtenu. Le but du programme étant de comparer, cycle après cycle, des formes d'ondes censées être semblables, pour évaluer les différences. Et en plus, comme elles sont censées se répéter à intervalle régulier et prédéfini, je désire les représenter sur un cercle, et non sur une droite, comme on le fait d'habitude, afin de mettre en évidence un éventuel décalage. Et ça n'est pas encore tout à fait fini : pour pouvoir comparer deux formes d'onde successives, je représente la forme "courante" sur un cercle externe, et la forme précédente sur un cercle intérieur.
Pour pouvoir faire cela, il faut effacer le tracé précédent. Mais au lieu de faire un "CLS", je tente d'effacer "point par point" le tracé précédent.
Après divers tâtonnements, j'en suis venu à la conclusion qu'il me fallait 4 buffers de son : celui qui est en train de se remplir est tracé "en temps réel" sur le cercle externe, alors que celui que j'ai tracé au cycle précédent doit être effacé du cercle externe et tracé sur le cercle interne, après que celui du cercle interne ait été effacé.
Pour avoir cet effet visuel "temps réel", ces différentes opérations sont faites sous le contrôle d'un "timer" au rythme de un appel toutes les millisecondes : voici le code :J'ai dit que le cycle était prédéfini. Je le contrôle avec le "PerformanceCounter" de Windows, qui est prétendument plus précis que la microseconde...
Code vb6 : 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 Private Sub Timer1_Timer() Dim t As Currency, alpha As Single, i As Integer, s As Single, c As Single Const Eps As Single = 0.75 QueryPerformanceCounter t alpha = (t - t0) / CPeriode If alpha > alpha0 + 1 Then 'changement de période buf = (buf + 1) Mod 4 Coul = 1 - Coul alpha0 = alpha ' alpha0 : compte les tours; DEUXPI * (alpha-alpha0) : angle waveInPrepareHeader DevHandle, VarPtr(Wave(buf)), LInData waveInAddBuffer DevHandle, VarPtr(Wave(buf)), LInData t1 = t t2 = t Else For i = (t2 - t1) / CPas To (t - t1) / CPas s = Sin(DEUXPI * i / nbpas) c = Cos(DEUXPI * i / nbpas) Picture1.PSet (InData((buf + 3) Mod 4, i) * s, InData((buf + 3) Mod 4, i) * c), vbWhite Picture1.PSet (InData(buf, i) * s, InData(buf, i) * c), couleur(Coul) Picture1.PSet (InData((buf + 2) Mod 4, i) * Eps * s, InData((buf + 2) Mod 4, i) * Eps * c), vbWhite Picture1.PSet (InData((buf + 3) Mod 4, i) * Eps * s, InData((buf + 3) Mod 4, i) * Eps * c), couleur(1 - Coul) Next t2 = t End If End Sub
CPeriode est la durée théorique d'un cycle, et Cpas est la période à laquelle le sont est échantillonné, ces deux valeurs étant mesurées dans l'unité du "PerformanceCouneter", qui utilise le type "Currency" de VB6 (équivalent des entiers 64 bits).
Je remercie ceux qui sont venus jusqu'ici. Je ne suis pas sûr qu'il soit intéressant d'entrer dans le détail des choix que j'ai fait pour réaliser mon projet, mais venons-en à mon problème, qui se situe dans la boucle avec les 4 Picture1.Pset : il me semble bien que, pour chaque indice "i" des 4 buffers qui sont remplis successivement par le micro, je fais les opérations successives suivantes : écriture sur le cercle externe, soit en rouge, soit en noir, puis écriture au même endroit en blanc, puis écriture sur le cercle interne, soit en noir, soit en rouge, puis écriture au même endroit en blanc. et que ces opérations sont "entrelacées" avec celles des autres indices et des autres buffers de telle façon que chaque sonogramme se développe progressivement, en remplaçant le précédent.
Eh bien ça ne marche pas : je vois parfois rien, parfois un quart de cercle avec du rouge et du noir mélangé. Évidemment, j'ai pu faire une erreur de raisonnement (mais j'ai quand-même pas mal réfléchi...) mais je me demande si la réponse ne serait pas dans telle ou telle "optimisation", soit de VB6, soit de Windows, soit du BIOS, qui changerait l'ordre d'exécution des écritures de pixels.
Je ne doute pas que ceux qui sont venus jusqu'ici sauront répondre à cette question. Et si c'est "oui", est-il possible de l'empêcher ?
Merci d'avance.
AMIcalement.
Partager