Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
openatelier:projet:sequences_etranges [2020/06/02 01:08]
emoc
openatelier:projet:sequences_etranges [2021/07/26 12:26] (Version actuelle)
emoc [séquence étrange trois]
Ligne 1: Ligne 1:
 +{{tag>​audio processing chuck em}}
 +
 ====== Séquences étranges ====== ====== Séquences étranges ======
  
 (Notes... 1er juin 2020) (Notes... 1er juin 2020)
  
-Jouets sonores. ​+Jouets sonores. ​Croquis de code pour des petites interfaces graphiques. Fonctionnels,​ mais sûrement avec des bugs surprises cachés dans les coins... Documentation minimale type prise de note
  
 ===== séquence étrange trois ===== ===== séquence étrange trois =====
  
 +juillet 2021 : publication de ce projet amélioré sur github : [[https://​github.com/​emoc/​bouclette|bouclette]] \\
 Boucles de samples type granulaire : à partir du même fichier sonore, boucler des petits fragments rapidement. Boucles de samples type granulaire : à partir du même fichier sonore, boucler des petits fragments rapidement.
  
Ligne 12: Ligne 15:
  
 {{http://​emoc.org/​ATELIER/​processing3/​2020_KI/​sequences_etranges/​sequence_etrange_trois_001/​test2.webm?​800x400|exemple vidéo}} {{http://​emoc.org/​ATELIER/​processing3/​2020_KI/​sequences_etranges/​sequence_etrange_trois_001/​test2.webm?​800x400|exemple vidéo}}
 +
 +==== code ====
 +
 +Un script processing pour l'​interface graphique et un script chuck pour le granulateur,​ les deux communiquent par OSC
 +
 +<​accordion>​
 +<panel title="​sequence_etrange_trois_001.pde (cliquer pour afficher le code)">​
 +<code java sequence_etrange_trois_001.pde>​
 +/*
 +  Discussions entre processing et chuck
 +  Lire en boucle plusieurs grains de sons d'un même fichier
 + ​Quimper,​ Dour Ru, 20200601 / pierre@lesporteslogiques.net
 + ​Processing 3.5.3 + ControlP5 2.2.6 + OscP5 0.9.9
 + chuck version: 1.4.0.1 linux (pulse) 64-bit
 + @ kirin / Debian Stretch 9.5
 +*/
 +
 +import oscP5.*;
 +import netP5.*;
 +OscP5 oscP5;
 +NetAddress myRemoteLocation;​
 +
 +ArrayList<​Grain>​ grains = new ArrayList<​Grain>​();​
 +
 +int id = 0;
 +float duree_morceau = 58.16; // en secondes
 +float dur;
 +
 +PImage wave;
 +
 +void setup() {
 +  size (800, 400);
 +  oscP5 = new OscP5(this, 12000);
 +  myRemoteLocation = new NetAddress("​127.0.0.1",​ 12012);
 +  wave = loadImage("​wf.png"​);​
 +}
 +
 +void draw() {
 +
 +  background(0);​
 +  image(wave,​0,​0);​
 +
 +  // Montrer la position et le fragment bouclé
 +  fill(128, 50);
 +  stroke(128, 50);
 +  strokeWeight(0.5);​
 +  dur = (((duree_morceau * 44100) / width) / ((mouseY / (float)height) * (3 * 44100))); ​
 +  float pixels_par_seconde = (float)width / duree_morceau;​ // x pixel = 1 seconde
 +  float duree_extrait = (1 - (mouseY / (float)height)) * 3 ; // 3 secondes max
 +  dur = pixels_par_seconde * duree_extrait;​
 +  ​
 +  line(0, mouseY, width, mouseY);
 +  rect(mouseX,​ 0, dur, height);
 +  for (int i = grains.size() - 1; i >= 0; i--) {
 +    Grain g = grains.get(i);​
 +    g.miseajour();​
 +  }
 +}
 +
 +void keyPressed() {
 +  if (key == '​p'​) ajouterGrain();​
 +  if (key == '​d'​) supprimerGrain(mouseX,​ mouseY);
 +  if (key == '​c'​) resetGrain();​
 +}
 +
 +void ajouterGrain() {
 +  id ++;
 +  if (id < 100) {
 +    grains.add( new Grain(mouseX,​ mouseY, id) );
 +
 +    OscMessage myMessage = new OscMessage("/​sequence_etrange_trois"​);​
 +    float xn = mouseX / (float)width; ​ // normaliser les valeurs
 +    float yn = mouseY / (float)height;​ // normaliser les valeurs
 +    myMessage.add(1);​
 +    myMessage.add(id);​
 +    myMessage.add(xn);​
 +    myMessage.add(1 - yn); // inverser, c'est plus intuitif, le zéro est en bas!
 +    oscP5.send(myMessage,​ myRemoteLocation);​
 +  } else {
 +    background(255,​ 0, 0);
 +    println("​trop de fragments!"​);​
 +  }
 +}
 +
 +void supprimerGrain(float x, float y) {
 +  for (int i = grains.size() - 1; i >= 0; i--) {
 +    Grain g = grains.get(i);​
 +    if (dist(x, y, g.x, g.y) < 6) {
 +      grains.remove(i);​
 +      OscMessage myMessage = new OscMessage("/​sequence_etrange_trois"​);​
 +      myMessage.add(0);​
 +      myMessage.add(g.id);​
 +      myMessage.add(0);​
 +      myMessage.add(0);​
 +      oscP5.send(myMessage,​ myRemoteLocation);​
 +    }
 +  }
 +}
 +
 +void resetGrain() {
 +  for (int i = grains.size() - 1; i >= 0; i--) {
 +    Grain g = grains.get(i);​
 +    grains.remove(i);​
 +    OscMessage myMessage = new OscMessage("/​sequence_etrange_trois"​);​
 +    myMessage.add(0);​
 +    myMessage.add(g.id);​
 +    myMessage.add(0);​
 +    myMessage.add(0);​
 +    oscP5.send(myMessage,​ myRemoteLocation);​
 +  }
 +  id = 0;
 +}
 +
 +class Grain {
 +  ​
 +  float x, y;                        // coordonnées à l'​écran (en pixels)
 +  int id;
 +    ​
 +  Grain(float x_, float y_, int id_) {
 +    x = x_;
 +    y = y_;
 +    id = id_;
 +  }
 +  ​
 +  void miseajour() {
 +    noFill();
 +    stroke(255, 200);
 +    strokeWeight(1);​
 +    line(x, y-5, x, y+5);
 +    line(x-5, y, x+5, y);
 +  }
 +}
 +</​code>​
 +</​panel>​
 +</​accordion>​
 +
 +<​accordion>​
 +<panel title="​sequence_etrange_trois_recepteur.ck (cliquer pour afficher le code)">​
 +<code sequence_etrange_trois_recepteur.ck>​
 +// Debian 9.5 @ kirin
 +// Chuck 1.4.0.1 linux (pulse) 64-bit
 +// 20200601 / pierre@lesporteslogiques.net
 +
 +OscIn oin;             // définir le récepteur OSC
 +12012 => oin.port; ​    // port de réception
 +OscMsg msg;
 +
 +oin.addAddress( "/​sequence_etrange_trois"​ );
 +
 +int fragments[100];​ // Pour stocker les id et les numéros de shred...
 +
 +while(true) {
 +  oin => now;
 +  ​
 +  while (oin.recv(msg) != 0) {
 +    msg.getInt(0) ​  => int action;
 +    msg.getInt(1) ​  => int index;
 +    msg.getFloat(2) => float start;
 +    msg.getFloat(3) => float dur;
 +    ​
 +    if (action == 0) { // Supprimer le shred associé à cet id
 +      <<<​ "​supprimer index " , index, "​fragments : ", fragments[index] >>>;​
 +      Machine.remove(fragments[index]);​
 +    }
 +    ​
 +    if (action == 1) { // Démarrer un nouveau shred
 +      Shred s;
 +      spork ~ grain(start,​ dur) @=> s;
 +      <<<​ "Index : " , index, " > nouveau shred : " , s.id() >>>;​
 +      s.id() => fragments[index];​
 +    }
 +  }
 +}
 +
 +fun void grain(float start, float dur) {
 +
 +  SndBuf gra => dac;
 +  me.dir() + "/​kabuki_sound_effects.wav"​ => gra.read;
 +  while(1) {
 +    ​
 +    (dur * 3 * 44100) $ int => int gradur;
 +    (start * gra.samples()) $ int => gra.pos;
 +    if (gra.pos() < 0) 0 $ int => gra.pos;
 +    gradur :: samp => now;
 +  }
 +}
 +</​code>​
 +</​panel>​
 +</​accordion>​
 +
 +==== petites choses utiles ====
 +
 +L'​image de la forme d'onde est créée avec [[https://​github.com/​bbc/​audiowaveform|audiowaveform]] (nécessaire d'​indiquer la durée du son)
 +  # 20200601 debian 9.5 @ kirin
 +  audiowaveform -i ./son.wav -s 0 -e 58.16 --background-color 000000 --waveform-color dddddd --no-axis-labels -w 800 -h 100 -o wf.png
 +
 +La capture vidéo est faite avec ffmpeg (cf. https://​trac.ffmpeg.org/​wiki/​Capture/​Desktop)
 +  # ffmpeg version 3.2.14-1~deb9u1
 +  # dans les controles de pulseaudio, dans l'​onglet "​Enregistrement"​ il faut régler "​Monitor of audio interne analogique"​
 +  ffmpeg -video_size 800x400 -framerate 25 -f x11grab -i :0.0+465,21 -f pulse -ac 2 -i default test2.mp4
 +
 +Les coordonnées de la fenêtre sont récupérées par (cf. https://​unix.stackexchange.com/​q/​14159)
 +  sleep 5s && xdotool getactivewindow getwindowgeometry
 +En fait ça n'est pas tout à fait la position mais je n'ai pas cherché plus loin, j'ai juste enlevé 22 pixels à la position verticale pour que ce soit à peu près bien cadré... ​
 +
 +===== Ressources =====
 +  * ChucK doc : https://​chuck.cs.princeton.edu/​doc/​language/ ​
 +  * ChucK ugens : https://​chuck.cs.princeton.edu/​doc/​program/​ugen_full.html
 +
 +
 +
  
  
  • openatelier/projet/sequences_etranges.1591052930.txt.gz
  • Dernière modification: 2020/06/02 01:08
  • par emoc