Dimanche, 10 mai

Nous avons essentiellement terminé notre projet, ayant complété la majorité de nos buts. L’application contient maintenant quatre tambours, dont une cymbale, un tom, un hi-hat et un snare, qui sont tous interchangeables et remplaçables. Il suffit simplement de se rendre dans le fichier data du fichier Airdrum et de changer les fichiers audio .mp3 ou de changer leurs noms. Cependant, on doit conserver les noms des fichiers audio existants, sinon on doit les changer à l’intérieur du code aussi. Nous avons trouvé que ce projet a testé nos connaissances de programmation. Bien sûr, sans le changement de plans nécessaire, il y aurait eu beaucoup plus de physique et de mathématiques à réaliser, mais nous avons fait notre possible pour en conserver le plus possible.

Voici une vidéo explicative sur notre projet:

Ci-dessous se retrouve le code écrit en Java contenu dans le logiciel Processing, si vous voulez simplement télécharger le projet au complet, rendez vous sur le site principal et cliquez sur le bouton pour télécharger ce dernier.

/* ATTENTION: Attendre deux secondes avec les 
couleurs devant la webcam avant de frapper. */

/* Pour un meilleur fonctionnement, utiliser 
une webcam sans balance des blancs automatique. */

import processing.video.*;
import processing.sound.*;
import lord_of_galaxy.timing_utils.*;

// Pour capturer la vidéo de la webcam
Capture video;

// Fichiers de sons
SoundFile snareFile;
SoundFile crashFile;
SoundFile tomFile;
SoundFile hihatFile;

// Couleur rouge et bleue
color trackColorRed;
color trackColorBlue;
float thresholdRed = 125; // changer ces valeurs pour trouver les meilleures
float thresholdBlue = 80;  // selon votre caméra et votre éclairage

// Tambours (instruments)
boolean snareSound = true;
boolean crashSound = true;
boolean tomSound = true;
boolean hihatSound = true;

// Pour stocker les valeurs de Y pendant 1 seconde
ArrayList<Float> listAvgYRed = new ArrayList<Float>(59);
float frameRed = 0;
ArrayList<Float> listAvgYBlue = new ArrayList<Float>(59);
float frameBlue = 0;

// Pour le temps
boolean timeRestartRed = true;
Stopwatch timeRed = new Stopwatch(this);
boolean timeRestartBlue = true;
Stopwatch timeBlue = new Stopwatch(this);

// Vitesse à laquelle vous allez jouer
float playSpeed = 10;

void setup() {
  // Détermine la taille de l'écran pour visionner la vidéo de la webcam
  size(640, 480);
  
  // Fait une liste des caméras, vous devez choisir la vôtre
  String[] cameras = Capture.list();
  // printArray(cameras);
  video = new Capture(this, cameras[1]);  // (choisissez l'indice de la caméra ici)
  
  // Fichiers de sons
  snareFile = new SoundFile(this, "snare.mp3");
  crashFile = new SoundFile(this, "cymbal.mp3");
  tomFile = new SoundFile(this, "tom.mp3");
  hihatFile = new SoundFile(this, "hihat.mp3");
  
  // Commence l'enregistrement de la webcam
  video.start();
  
  // Ce sont les couleurs à reconnaître (changez si vous avez d'autres couleurs)
  trackColorRed = color(255,0,0);  // en code RGB, donc 0 à 255
  trackColorBlue = color(14, 138, 209);  // exemple: jaune -> (255, 255, 0)
}

void captureEvent(Capture video) 
{
  // Permet de lire la vidéo
  video.read(); 
}

void draw(){
  // Pour transmettre la vidéo à l'écran
  video.loadPixels();
  
  // Pour la vidéo avec effet miroir
  pushMatrix();
  translate(width,0);
  scale(-1,1);
  image(video, 0, 0, width, height);  // affiche la vidéo
  popMatrix();
  
  // Pour le rouge
  float avgXRed = 0;
  float avgYRed = 0;
  int countRed = 0;
  
  // Pour le snare
  rect(540, 300, 100, 100);
  
  // Pour le hi-hat
  rect(420, 300, 100, 100);
  
  // On trouve la concentration de rouge dans la vidéo
  for (int x = 0; x < video.width; x++) {
    for (int y = 0; y < video.height; y++){
      int locRed = x + y*video.width;
      color currentColor = video.pixels[locRed];
      float r1 = red(currentColor);
      float g1 = green(currentColor);
      float b1 = blue(currentColor);
      float rRed = red(trackColorRed);
      float gRed = green(trackColorRed);
      float bRed = blue(trackColorRed);
      float dRed = dist(r1, g1, b1, rRed, gRed, bRed);
      
      if (dRed < thresholdRed){
        avgXRed += x;
        avgYRed += y;
        countRed++;
      }
    }
  }
  
  // Pour le bleu
  float avgXBlue = 0;
  float avgYBlue = 0;
  int countBlue = 0;
  
  // Rectangle de la cymbale
  rect(0, 300, 100, 100);
  
  // Rectangle du tom
  rect(120, 300, 100, 100);
  
  // On trouve la concentration de bleu dans la vidéo
  for(int x = 0; x < video.width; x++) {
    for(int y = 0; y < video.height; y++) {
      int locBlue = x + y*video.width;
      color currentColor = video.pixels[locBlue];
      float r2 = red(currentColor);
      float g2 = green(currentColor);
      float b2 = blue(currentColor);
      float rBlue = red(trackColorBlue);
      float gBlue = green(trackColorBlue);
      float bBlue = blue(trackColorBlue);
      float dBlue = dist(r2, g2, b2, rBlue, gBlue, bBlue);
      
      if (dBlue < thresholdBlue){
        avgXBlue += x;
        avgYBlue += y;
        countBlue++;
      }
    }
  }
  
      // Pour le rouge
      if (countRed > 0 ) 
      {
        // On positionne un cercle où la moyenne du rouge est situé dans l'écran
        avgXRed = avgXRed / countRed;
        avgYRed = avgYRed / countRed;
      
        // On rempli les rectangles et le cercle de rouge
        fill(trackColorRed);
        strokeWeight (4.0);
        stroke(0);
        
        // Pour suivre le rouge avec x inversé
        ellipse(-avgXRed +width,avgYRed,16,16);
        
        // On ajoute la position à la liste de valeurs Y de rouge
        listAvgYRed.add(avgYRed);
        frameRed++;
        
        // À chaque fois que le frame spécifié est enregistré
        if (frameRed % playSpeed == 0 && timeRestartRed == true)
        {  
           timeRed.start();  // on commence le timer
           timeRestartRed = false;
        }
        
        // Si une frappe de snare est détectée
        if(snareSound == true && avgYRed>=300 && avgYRed<=400 && avgXRed<=105)
        {
          // Calcule la vitesse de la frappe
          float distance = 300 - listAvgYRed.get(56); // 0.06 sec avant la frappe
          float temps = timeRed.time();  // temps écoulé depuis le 56ième frame
          float vitesse = (distance/temps) * 100;  /* fois 100 pour avoir des
                                                      plus gros ratios */
          // Frappe plus forte
          if (vitesse >= 10)
          {
            snareFile.amp(1);
          }
          
          // Frappe moins forte
          if (vitesse < 10)
          {
            snareFile.amp(0.3); 
          }
          
          // Joue le son du snare
          snareFile.play();
          snareSound = false;
          
          // Permet de recommencer le timer
          timeRestartRed = true;
        }
        
        // Après une frappe de snare
        if(snareSound == false && avgYRed<=300)
        {
          snareSound = true;  // permet de refrapper le snare
        }
        
        // Si une frappe de hihat est détectée
        if(hihatSound == true && avgYRed>=300 && avgYRed<=400 && avgXRed<=225 && avgXRed>=115)
        {
          // Calcule la vitesse de la frappe
          float distance = 300 - listAvgYRed.get(56); // 0.06 sec avant la frappe
          float temps = timeRed.time();  // temps écoulé depuis le 56ième frame
          float vitesse = (distance/temps) * 100;  /* fois 100 pour avoir des
                                                      plus gros ratios */
          // Frappe plus forte
          if (vitesse >= 10)
          {
            hihatFile.amp(0.6);
          }
          
          // Frappe moins forte
          if (vitesse < 10)
          {
            hihatFile.amp(0.1); 
          }
          
          // Joue le son du hi-hat
          hihatFile.play();
          hihatSound = false;
          
          // Permet de recommencer le timer
          timeRestartRed = true;
        }
        
        // Après une frappe de hihat
        if (hihatSound == false && avgYRed<=300)
        {
           hihatSound = true;  // permet de refrapper le hihat 
        }
      }
      
  // Si la liste de valeurs du Y du rouge est plein
  if (listAvgYRed.size() >= 59)
  {
    listAvgYRed.remove(0);  // on enlève le premier élément
  }
      
      // Pour le bleu
      if (countBlue > 0) 
      {
        // On positionne un cercle où la moyenne du bleu est situé dans l'écran
        avgXBlue = avgXBlue / countBlue;
        avgYBlue = avgYBlue / countBlue;
      
        // On rempli les rectangles et le cercle de bleu
        fill(trackColorBlue);
        strokeWeight(4.0);
        stroke(0);
        
        // Pour suivre le bleu avec x inversé
        ellipse(-avgXBlue + width, avgYBlue, 16, 16);
        
        // On ajoute la position à la liste de valeurs Y de bleu
        listAvgYBlue.add(avgYBlue);
        frameBlue++;
        
        // À chaque fois que le frame spécifié est enregistré
        if (frameBlue % playSpeed == 0 && timeRestartBlue == true)
        {  
           timeBlue.start();  // on commence le timer
           timeRestartBlue = false;
        }
        
        // Si une frappe de cymbale est détectée
        if (crashSound == true && avgYBlue>=300 && avgYBlue<=400 && avgXBlue>=535)
        {
          // Calcule la vitesse de la frappe
          float distance = 300 - listAvgYBlue.get(56); // 0.06 sec avant la frappe
          float temps = timeBlue.time();  // temps écoulé depuis le 56ième frame
          float vitesse = (distance/temps) * 100;  /* fois 100 pour avoir des
                                                      plus gros ratios */
          // Frappe plus forte
          if (vitesse >= 10)
          {
            crashFile.amp(0.8);
          }
          
          // Frappe moins forte
          if (vitesse < 10)
          {
            crashFile.amp(0.2); 
          }
          
          crashFile.play();  // on joue le son du crash (cymbale)
          crashSound = false;
          
          // Permet de recommencer le timer
          timeRestartBlue = true;
        }
        
        // Après la frappe de cymbale
        if (crashSound == false && avgYBlue<=300)
        {
          crashSound = true;  // permet de refrapper la cymbale
        }
        
        // Si une frappe de tom est détectée
        if (tomSound == true && avgYBlue>=300 && avgYBlue<=400 && avgXBlue<=525 && avgXBlue>=415)
        {
          // Calcule la vitesse de la frappe
          float distance = 300 - listAvgYBlue.get(56); // 0.06 sec avant la frappe
          float temps = timeBlue.time();  // temps écoulé depuis le 56ième frame
          float vitesse = (distance/temps) * 100;  /* fois 100 pour avoir des
                                                      plus gros ratios */
          // Frappe plus forte
          if (vitesse >= 10)
          {
            tomFile.amp(0.8);
          }
          
          // Frappe moins forte
          if (vitesse < 10)
          {
            tomFile.amp(0.2); 
          }
          
          tomFile.play();  // on joue le son du tom
          tomSound = false;
          
          // Permet de recommencer le timer
          timeRestartBlue = true;
        }
        
        // Après la frappe de tom
        if (tomSound == false && avgYBlue<=300)
        {
          tomSound = true;  // permet de refrapper le tom
        }
      }
      
  // Si la liste de valeurs du Y du rouge est plein
  if (listAvgYBlue.size() >= 59)
  {
    listAvgYBlue.remove(0);  // on enlève le premier élément
  }
}

Mardi, 5 mai

Nous avons réussi à déterminer l’intensité des frappes. Cependant, c’est plutôt un estimé de l’intensité de la frappe, puisqu’il est pratiquement impossible de déterminer quand une frappe « commence » (composante en y initiale) sans avoir un bouton ou un certain dispositif pour nous aider à déterminer ce moment. Alors, nous avons estimé l’intensité de la frappe. De plus, la librairie Sound de Processing nous permet de régler l’amplitude du son .mp3 que nous avons donné au programme. Ceci dit, nous n’utiliserons pas de langage MIDI pour le restant du projet, puisque changer l’amplitude du son est déjà possible seulement avec du code d’une librairie.

Pour arriver à estimer la vitesse d’une frappe, nous avons défini une ArrayList, qui est un tableau dynamique, donc qui change de grandeur tout seul, et où il est facile d’ajouter et de supprimer des éléments. Dans notre cas, cette liste est utilisée pour stocker les frames (qui est l’image affichée sur l’écran, à chaque seconde elle change habituellement). Étant donné que Processing affiche des images à 60fps par défaut, nous avons créé une liste de 59 éléments, ce qui inclut le 0 pour donner 60 éléments au total. La liste enregistre constamment les positions de la baguette. Lorsque la liste est pleine de 60 éléments, le premier élément se fait supprimer, et l’entièreté des éléments se tassent vers le début pour permettre à un nouveau élément de rentrer à la fin de la liste. Ce cycle se déroule sans arrêt.

Enfin, pour calculer une vitesse, il faut une distance (ici, la distance entre le tambour et la baguette au début de la frappe) et un temps (ici, le temps entre le début de la frappe et le tambour). En ce qui concerne la distance, nous avons décidé de prendre la liste des 60 dernières positions de la baguette et de prendre la valeur à l’élément 56, en d’autres mots, 4 frames avant la frappe. Évidemment, dans notre cas, nous n’avons pas besoin de tous ces autres frames, mais c’est parce qu’on va jouer au drum relativement vite. Pour quelqu’un qui ne jouera pas aussi vite que nous, il pourra changer le code pour prendre la valeur à l’élément 34, par exemple. Par contre, pour nous, l’élément 56 fonctionne parfaitement. Donc, nous prenons la position de la baguette à ce 56e frame et nous trouvons la distance entre le tambour et cette dernière. Pour la différence de temps entre ces deux moments, il suffit simplement de partir un chronomètre à chaque 4 frames avec un modulo, puis arrêter ce chronomètre lorsqu’une frappe est exécutée. Bref, c’est pour ces raisons que la vitesse que nous calculons est un estimé.

Voici le code en lien avec ces explications (seulement pour le rouge, pour éviter la redondance):

Voir « pour stocker les valeurs de Y pendant 1 seconde » et « pour le temps ».
Voir « on ajoute la position à la liste de valeurs de Y de rouge » et « à chaque fois que le frame 56 est enregistré ».
Voir « calcule la vitesse de la frappe », « frappe plus forte », « frappe moins forte » et « permet de recommencer le timer ».
Voir « si la liste de valeurs du Y du rouge est plein ».

Sources:

Comment utiliser une ArrayList: https://www.w3schools.com/java/java_arraylist.asp

Pour faire un timer: https://github.com/Lord-of-the-Galaxy/Timing-Utilities

Pour les sons .mp3: https://www.fesliyanstudios.com/

Samedi, 2 mai

Nous avons réussi à suivre deux baguettes sur l’écran, de couleurs différentes bien sûr. C’était assez simple, il fallait simplement recopier le code pour la première baguette en s’assurant de dupliquer les variables et les paramètres, quelques-uns pour le rouge et d’autres pour le bleu.

Cependant, comme on peut voir dans la vidéo ci-dessus, il y a une erreur au niveau des couleurs des carrés. En effet, dans avec le langage Java dans Processing, on peut seulement régler la couleur de toutes les formes en même temps. Alors lorsqu’on tente de changer la couleur de deux carrés différents, ça ne marche pas, puisque les deux formes prennent la même couleur simultanément. Si nous ne sommes pas capables de trouver une solution efficace, nous pourrions juste laisser tomber l’idée de carrés qui ont la même couleur que la baguette associée (bleu à gauche, rouge à droite, ou vice versa).

En ce qui concerne les ajustements apportées au code, nous avons seulement ajouté les variables et paramètres pour la couleur bleu en prenant soin de distinguer leur nom des variables et paramètres pour la couleur rouge. De plus, nous avons inversé l’image de la webcam, pour reproduire l’effet d’un miroir. Il suffit d’ajouter ces lignes de code après l’instanciation de la vidéo:

Dans le code, voir « pour la vidéo avec effet miroir ».

Or, il ne faut pas oublier de modifier le système qui suit les couleurs, sinon il affichera le contraire en composante x. Voici les modifications:

Dans le code, voir « pour suivre [la couleur] avec x inversé ».

Mardi, 28 avril

Nous avons essayé d’ajouter du son dans notre projet. Nous avons commencé par inclure la librairie Sound de The Processing Foundation. Ensuite, en s’aidant d’une vidéo YouTube, nous avons réussi à prendre un fichier .mp3 et le mettre dans le programme pour qu’il joue. Nous avons par la suite déterminé un intervalle de position en X et en Y dans laquelle le son sera joué si la couleur rouge est reconnue. Étant donné que cette méthode était dans le draw(), elle s’appelait à chaque image, donc le son jouait sans arrêt allant jusqu’à faire “bugger” le programme. Pour arriver à surmonter ce problème, nous devions instancier une variable égale à 0 ou à 1 en dehors du draw() qui permettrait de savoir si la baguette était dans la zone du tambour ou non, et envoyer l’information afin de faire jouer le son une seule fois lorsque la baguette est reconnue.

Dimanche, 26 avril

Nous avons écouté certaines vidéos pour se familiariser avec Processing et Java, mais nous avons vite vu que Java ressemble beaucoup à C#, donc nous n’avions pas vraiment de difficulté à comprendre comment nous allions coder avec ce language. Nous avons donc directement commencé à se familiariser avec le Color Tracking.

La première chose que nous avons dû faire est installer la librairie Video faite par The Processing Foundation. Cette librairie nous permettra de prendre en entrée la vidéo de notre WebCam et de l’afficher par la suite dans la fenêtre de processing. Ensuite, nous avons suivi les étapes des vidéos mentionnées dans notre bibliographie pour réussir à avoir une fenêtre avec notre WebCam qui soit capable de faire du “Color Tracking”.

Le programme prend essentiellement chaque pixel de couleur dans l’écran puis les compare les uns avec les autres pour trouver le candidat qui sera le plus proche de la couleur recherchée (ici, le rouge) à l’aide de la méthode de la distance Euclidienne, qui choisira donc le meilleur résultat possible à l’intérieur du cadre de l’écran. Une fois le meilleur résultat choisi, il créera donc un cercle rouge qui se placera à la position où la couleur était la plus forte, et la méthode draw() fera donc ces calculs constamment jusqu’à ce que le programme soit fermé.

Mardi, 21 avril

Nous avons pris la décision de changer de Unity à Processing pour le moment. Après avoir fait plusieurs recherches, nous avons fini par constater que les bibliothèques disponibles pour atteindre notre objectif final étaient beaucoup plus nombreuses sur Processing, même chose pour les ressources disponibles sur internet. Pour Unity, nous n’étions pas surs d’être en mesure d’avoir un résultat de la même qualité sans utiliser des « engines » pour le « motion tracking », qui d’ailleurs étaient en majorité payants. Nous allons donc laisser de côté ce que nous avions commencé sur Unity afin de se concentrer sur le language Processing, en Java.

Ci-dessous sont deux vidéos qui pourront nous être utiles pour commencer notre projet à travers Processing:

Dimanche, 19 avril

En utilisant la méthode de chercher la couleur rouge dans Unity, nous avons rencontré deux problèmes:

  1. La méthode GetPixels reconnaît plusieurs fois le ballon rouge au-bas de la texture, donc le son jouait souvent.
  2. En initialisant le programme, les valeurs de RGB sont tous à 1, puis descendent immédiatement à 0, mais au tout début la valeur de rouge est plus grand que 0.9, donc le son est joué.

La deuxième erreur était simple à résoudre. En effet, ce n’était même pas dû au fait que les valeurs de RGB étaient initialisées à 1 au lancement du programme, il fallait simplement décocher la paramètre Play on Awake du GameObject dans la scène de Unity.

La première erreur a fallu plusieurs lignes de code pour résoudre, mais ce n’est rien de complexe. En gros, nous avons définit une variable booléenne goingDown qui détermine si la baguette se dirige vers le bas pour exécuter une frappe ou non. Lorsque goingDown est vraie, le programme cherche à identifier les pixels rouges au bas de l’écran, comme avant. Lorsque la frappe est exécutée (le son est joué), la variable goingDown est mise à fausse, pour ne pas engendrer plus de frappes. La baguette doit alors revenir en-haut de la texture de la webcam, où il y a maintenant un deuxième bloc d’identification de pixels rouges. Lorsque la baguette est identifiée en-haut, la variable est mise à nouveau à vraie, et le processus recommence.

De plus, de cette manière, le programme ne cherche pas constamment des pixels rouges au-bas et en-haut de la texture, seulement l’endroit où il est nécessaire. Voici un test du programme à ce stade-ci:

Samedi, 18 avril

Aujourd’hui, nous commençons à tester Unity pour premièrement comprendre comment fonctionne l’implémentation de la vidéo dans l’environnement Unity, ainsi que la détection de Webcam.

Nous avons cherché pour des moyens de reconnaître des mouvements sur la vidéo produite par une webcam d’ordinateur. Bien sûr, il faut tout d’abord afficher notre webcam dans un logiciel pour pouvoir travailler avec la vidéo. Étant donné que Unity a déjà une librairie intégrée qui permet d’utiliser une webcam, nous avons décidé de poursuivre avec ce logiciel. Le constructeur WebCamTexture permet d’afficher la vidéo enregistrée en live par une webcam sur une surface dans Unity.

Le constructeur WebCamTexture permet aussi de retourner les couleurs prédominantes en valeurs RGB (0 à 1) dans un certain bloc de pixels de la texture. C’est la méthode GetPixels, qui prend en paramètre la position d’un pixel en x et y, puis la hauteur et la largeur du bloc de pixels désiré. Grâce à cette méthode, nous pouvons reconnaître quelque chose dans la vidéo! Nous pouvons utiliser cette méthode GetPixels pour reconnaître un objet dans la vidéo de la webcam, comme les baguettes de la batterie virtuelle.

Nous avons testé avec un gros ballon rouge, trouvé chez moi, pour voir si cette technique allait bien fonctionner pour déterminer une frappe. Nous avons placé le bloc de détection de pixels au bas de la texture, puis nous avons fait des mouvement de va-et-vient avec le ballon rouge de haut en bas, comme pour simuler le mouvement d’une baguette de drum. Lorsque la méthode GetPixels retourne une valeur de rouge plus grand que 0.9, le programme jouait un son.

Nous nous sommes rendus compte de deux erreurs majeures:

  1. La méthode GetPixels reconnaît plusieurs fois le ballon rouge au-bas de la texture, donc le son jouait souvent.
  2. En initialisant le programme, les valeurs de RGB sont tous à 1, puis descendent immédiatement à 0, mais au tout début la valeur de rouge est plus grand que 0.9, donc le son est joué.

Pour la première erreur, nous pourrions implémenter un deuxième bloc GetPixels en-haut de la texture. De cette façon, on dirait au programme de jouer le son lorsqu’il voit le ballon rouge, comme d’habitude, sauf qu’il doit maintenant attendre de revoir le ballon en-haut de l’écran avant de pouvoir rejouer le son lorsqu’il le reverra en bas de la texture. Si nous conservons cette technique de suivre les mouvements avec les couleurs, il faudrait implémenter un deuxième bloc GetPixels de toute façon, pour pouvoir retourner la vitesse des baguettes pour savoir l’intensité du son à jouer.

Sources:

https://docs.unity3d.com/ScriptReference/WebCamTexture.html

https://www.youtube.com/watch?v=NKjxgjL95Aw

Mercredi, 15 avril

CHANGEMENT DE PLANS

Étant donné la situation actuelle du COVID-19, nous ne pourrons pas commander et avoir accès au matériel nécessaire pour complèter le projet précédemment envisagé. C’est pour cette raison que nous avons décidé de modifier le projet de AirInstruments pour pouvoir reprendre le fil à partir d’aujourd’hui. En ce qui concerne la guitare virtuelle, nous allons simplement enlever l’idée du projet, en souci de manque de temps, puisque la date de remise est le jeudi 14 mai. Il nous reste donc 28 jours pour réaliser la batterie virtuelle. Pour cette dernière, nous avons décidé d’enlever les accéléromètres, car nous ne pourrons pas en avoir, et de faire notre propre reconnaissance vidéo à la place, comme faire notre propre Kinect. Le programme sera en mesure de reconnaître notre corps et nos mouvements, et ce tout à travers une webcam ordinaire. Nous croyons que le code sera écrit principalement avec Unity ou Processing. En ce qui concerne le reste du projet, dont l’interface MIDI, il sera à voir comment l’utiliser pour interprèter nos mouvements, mais restera sûrement dans le projet. Bien sûr, toutes ces informations sont susceptibles de changer.

Mercredi, 11 mars

Aujourd’hui, j’ai construit les baguettes pour le drum virtuel. Il ne restera qu’à décider comment installer les accéléromètres dessus et ensuite, bien sûr, les installer. Voici le processus:

Tout d’abord, j’ai trouvé un long bâton de bois rectangulaire chez nous, puis je suis allé voir sur Google pour vérifier la longueur moyenne d’une baguette de drum. Cette recherche m’a informé qu’une baguette moyenne possède une longueur d’environ 15po à 17.5po, donc j’ai décidé de choisir une longueur de 16po, ce qui donne environ 41cm. J’ai donc mesuré deux longeurs consécutives de 41cm, puis j’ai coupé le bois avec une scie à table. Ensuite, j’ai sablé les baguettes pour enlever la peinture brune, et pour leur donner une forme particulière. Le manche est rond, pour avoir une certaine ergonomie. Cependant, j’ai laissé le bout au cou de la baguette en rectangle, pour qu’il soit plus facile de poser l’accéléromètre dessus. Enfin, j’ai terminé le tout avec deux couches de vernis, en attendant 30 minutes entre les couches.

Concevoir un site comme celui-ci avec WordPress.com
Commencer