Vos actions : Créer un document, voir la page générale.

Cultures numériques

Cours de Bachelor 1

Déclencher des sons à partir de la webcam

Ce script utilise la librairie vidéo (installée par défaut dans Processing) et la librairie Minim, à télécharger au besoin. Il permet de déclencher des notes générés (pas de fichier son nécessaire) quand certains zones de l’image de la webcam sont sombres.

Pour ce script, on définit des zones de l’image de la webcam, et on leur associe une note, et on a la possibilité de jouer sur le niveau de lumière qui déclenche le son (avec les flèches bas et haut du clavier).
Le code peut être copié-collé dans une fenêtre Processing.

// déclencher des sons synthétisés sur base de webcam
import processing.video.*;
import ddf.minim.*;
import ddf.minim.ugens.*;
Capture cam;
Minim minim;
AudioOutput out;

zone_son[] lazone=new zone_son[18];

float seuil=375;
boolean p=false;

void setup() {
  size(800, 600);
  cam = new Capture(this, width, height);
  cam.start();
  minim = new Minim(this);  
  out = minim.getLineOut();
  // les zones et notes associées
  lazone[0]=new zone_son(width/2, 30, 30, 30, "C2");
  lazone[1]=new zone_son(width/2, 60, 30, 30, "D2");
  lazone[2]=new zone_son(width/2, 90, 30, 30, "E2");
  lazone[3]=new zone_son(width/2, 120, 30, 30, "F2");
  lazone[4]=new zone_son(width/2, 150, 30, 30, "G2");
  lazone[5]=new zone_son(width/2, 180, 30, 30, "A3");
  lazone[6]=new zone_son(width/2, 210, 30, 30, "B3");
  lazone[7]=new zone_son(width/2, 240, 30, 30, "C3");
  lazone[8]=new zone_son(width/2, 270, 30, 30, "D3");
  lazone[9]=new zone_son(width/2, 300, 30, 30, "E3");
  lazone[10]=new zone_son(width/2, 330, 30, 30, "F3");
  lazone[11]=new zone_son(width/2, 360, 30, 30, "G3");
  lazone[12]=new zone_son(width/2, 390, 30, 30, "A4");
  lazone[13]=new zone_son(width/2, 420, 30, 30, "B4");
  lazone[14]=new zone_son(width/2, 450, 30, 30, "C4");
  lazone[15]=new zone_son(width/2, 480, 30, 30, "D4");
  lazone[16]=new zone_son(width/2, 510, 30, 30, "E4");
  lazone[17]=new zone_son(width/2, 540, 30, 30, "F4");
}

void draw() {
  if (cam.available()) {
    // Reads the new frame
    cam.read();
    image(cam, 0, 0);
    for (int i=0; i< lazone.length; i++) {
      lazone[i].teste();
      lazone[i].dessine();
      lazone[i].joue();
    }
  }
  noStroke();
  fill(0, 150);
  rect(0, 0, 200, 30);
  fill(255);
  text("Seuil : "+seuil+" / 765", 10, 20);
}

// modifier le seuil avec les touches haut et bas
void keyPressed() {
  if (key==CODED) {
    if (keyCode==UP) {
      seuil+=5;
    }
    if (keyCode==DOWN) {
      seuil-=5;
    }
    seuil=constrain(seuil, 0, 765);
  }
}


class zone_son {
  int px, py, lx, ly;
  String note;
  boolean survol, joue;
  int surface;

  zone_son(int px, int py, int lx, int ly, String note) {
    this.px=px;
    this.py=py;
    this.lx=lx;
    this.ly=ly;
    surface=lx*ly;
    this.note=note;
    survol=false;
    joue=false;
  }

  void dessine() {
    stroke(255, 0, 0);
    if (survol==true) {
      fill(255, 0, 0);
    } else {
      noFill();
    }
    rect(px, py, lx, ly);
  }

  void joue() {
    if (survol==true && joue==false) {
      out.playNote( note );
      joue=true;
    } else if (survol==false && joue==true) {
      joue=false;
    }
  }

  void teste() {
    int presenceSum = 0;
    for (int x=px; x < px+lx; x++) {
      for (int y=py; y < py+ly; y++) {
        color currColor = cam.pixels[(y*width)+x];
        // Extract the red, green, and blue components of the current pixel’s color
        int cR = (currColor >> 16) & 0xFF;
        int cG = (currColor >> 8) & 0xFF;
        int cB = currColor & 0xFF;
        presenceSum += cR + cG + cB;
      }
    }

    //println(presenceSum/surface);
    if (presenceSum/surface < seuil) {
      survol=true;
    } else {
      survol=false;
    }
  }
}

Remarque : le son se déclenche quand la zone passe de claire à sombre, mais on peut inverser ce déclenchement.
Si on veut que le son se déclenche quand on passe du sombre au clair, on changera la ligne

if (presenceSum/surface < seuil) {

par

if (presenceSum/surface > seuil) {
Par Stéphane Noël, 25 novembre 2017