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

Cultures numériques

Cours de Bachelor 1

Exemples simples de génération de notes sur base de texte

Cet exemple utilise une phrase (ça marche mieux quand elle est courte) sur base dont chaque caractère, un par un, est transformé en note.

Les lettres et leur code

Les caractères dans un texte sur ordinateur sont la plupart du temps codés dans un octet, un groupe de 8 chiffres de 0 ou 1. Dans Processing on peut récupérer ce code et l’utiliser pour déterminer un son.

Chaque lettre correspond à un chiffre de la table ASCII. Voici un tableau des lettres et chiffres qui nous intéressent :

Dans ce tableau, on peut voir que la lettre A correspond au chiffre 65 et la lettre z au chiffre 122. Le script récupère la valeur de la lettre et la convertit en un chiffre de 0 à 18, qui correspond à une note.

On peut facilement changer la phrase (à côté de ’String s=’) et la vitesse de lecture en millièmes de secondes (ici 500, donc une demi-seconde).

Exemple 1 : des lettres vers des ondes

Un premier exemple avec la librairie sound permet de transformer les lettres en hauteur de note grâce à une conversion rapide.

import processing.sound.*;
SqrOsc square;

int trigger;
boolean lecture=false;
boolean loop=true;
int compteur=0;
char actuel;

// changer les parametres ici
// la phrase jouée
String s="erg ERG erg ERG ";
int vitesse = 150; // la vitesse entre deux beats en millièmes de secondes

void setup() {
  size(600, 600);
  textAlign(CENTER, CENTER);
  fill(0);
  square = new SqrOsc(this);
  square.amp(0.5);
  trigger = millis();
}

void draw() {
  background(255);
  fill(0);  
  if (lecture) {
    if (millis() > trigger) {
      actuel=s.charAt(compteur);
      int c = int(s.charAt(compteur));

      // transposer un chiffre de 48 à 122 vers une frequence de 200 à 700
      float frequence=map(c, 48, 122, 200, 700);
      square.freq(frequence);

      trigger = millis() + vitesse;
      compteur++;
      if (compteur > s.length()-1) {
        compteur=0;
        if (loop==false) {
          println("lecture finie");
          lecture=false;
          square.stop();
        }
      }
    }
  }

  text(s, width/2, height/2);
  textSize(30);
  text(actuel, width/2, height*0.33);
  textSize(12);

  text("tapez \"return\" pour lancer ou stopper le son, tapez \"L\" pour une lecture en boucle ou pas", width/2, height-100);

  if (loop) {
    rect(0, height-30, 50, 30);
    fill(255);
    text("LOOP", 25, height-15);
  }
}

void keyPressed() {
  if (key ==ENTER) {
    if (lecture==false) {
      lecture=true;
      println("lecture");
      square.play();
    } else {
      lecture=false;
      compteur=0;
      println("stop lecture");
      square.stop();
    }
  }
  if (key=='l' || key=='L') {
    if (loop==true) {
      loop=false;
    } else {
      loop=true;
    }
  }
}

Exemple 2 : des caractères vers des notes

// Lire des phrases et transposer les lettres en notes

import ddf.minim.*;
import ddf.minim.ugens.*;
Minim minim;
AudioOutput out;
int trigger;
boolean lecture=false;
boolean loop=true;
int compteur=0;
char actuel;

// changer les parametres ici 
// la phrase jouée
String s="Fuck you";
int vitesse = 500; // la vitesse entre deux beat en millieme de secondes

// les notes disponibles
String[] notes= {"C3", "D3", "E3", "F3", "G3", "A3", "B3", "C4", "D4", "E4", "F4", "G4", "A5", "B5", "C5", "D5", "E5", "F5", "G5"};
void setup() {
  size(600, 600);
  textAlign(CENTER, CENTER);
  fill(0);
  trigger = millis();
  minim = new Minim(this);
  // use the getLineOut method of the Minim object to get an AudioOutput object
  out = minim.getLineOut();
  out.setTempo( 80 );
}

void draw() {
  background(255);
  fill(0);  
  if (lecture) {
    if (millis() > trigger) {
      int c = int(s.charAt(compteur));
      actuel=s.charAt(compteur);
      // 48 à 122, doit de 0 à 9 et de a à Z
      c=int(map(c, 48, 122, 0, notes.length));
      c=constrain(c, 0, notes.length);
      out.playNote( notes[c] );
      println(s.charAt(compteur) + " : note "+notes[c]);
      trigger = millis() + vitesse;
      compteur++;
      if (compteur > s.length()-1) {
        compteur=0;
        if (loop==false) {
          println("lecture finie");
          lecture=false;
        }
      }
    }
  }

  text(s, width/2, height/2);
  textSize(30);
  text(actuel, width/2, height*0.33);
  textSize(12);

  text("tapez \"return\" pour lancer ou stopper le son, tapez \"L\" pour une lecture en boucle ou pas", width/2, height-100);

  if (loop) {
    rect(0, height-30, 50, 30);
    fill(255);
    text("LOOP", 25, height-15);
  }
}

void keyPressed() {
  if (key ==ENTER) {
    if (lecture==false) {
      lecture=true; 
      println("lecture");
    } else {
      lecture=false;
      compteur=0;
      println("stop lecture");
    }
  }
  if (key=='l' || key=='L') {
    if (loop==true) {
      loop=false;
    } else {
      loop=true;
    }
  }
}
Par Stéphane Noël, 26 novembre 2017