Who knows well Geomerative?!

Are you kiding?! No worries at all! You did a lot and helped me a lot on a sunday afternoon! Your help is very precious to me. Thank you so much dear @Chrisir

1 Like

Hey @Chrisir,

Almost there, but still stuck!
I have cleaned+simplified the sketch a bit and add the modifications you’v suggested…!
Now the sentences appear one after the other which is what I wanted. the problem is still that when I update, my attractor still deform all the sentences and not only the one that just appeared! I’d like that attractor 1 modifies sentence 1 according to sound 1, then we pass to attractor 2 which modifies sentence 2 according to sound 2, until sound 13 and the loop…
Sorry to bother agian. Thanks a lot in advance. best, L

import processing.pdf.*;
import geomerative.*;
import ddf.minim.analysis.*;
import ddf.minim.*;

//TEXT
int indexPhraseSetFR;
int indexPhraseFR;
int x, y, i, j;
String []message={
  "On me dit de te haïr et je m'y efforce", 
  "Je t'imagine cruel, violent, implacable", 
  "mais à te voir je n'ai bientôt plus de force", 
  "et de te blesser je suis bien incapable", 

  "Tous mes camarades combattent avec rage", 
  "Et pleurent la nuit au souvenir des supplices", 
  "Infligés à leurs frères qui sont du même âge", 
  "et rêvent comme eux de toucher une peau lisse", 

  "Et de pouvoir enfin caresser des obus", 
  "Autres que ceux produits par le pouvoir obtus", 
  "Je rêve de quitter ces boyaux infernaux", 

  "De laisser ces furieux des deux bords du Rhin", 
  "Et de pouvoir embrasser ta chute de rein", 
  "Et porter notre amour sur les fonts baptismaux"
};

color textColor=0;
RFont f;
float fontSize=60;
int splitGlyph = 120;
RPoint[][] pointsP;
float r = random(5, 20);
WordAttractor attractorW;
// We create 3 new lists parallel to pointsP
// List of attractors, one per glyph
WordAttractor [][] listWordAttractors;
// List of all the distances between all the attractors and the pointsP
float [][] listDistMap;
// List of vectors to replace the pointsP coordinates
PVector [][] listPV;

RShape [] gShape = new RShape[message.length]; 
characterSpec [] characters= new characterSpec[message.length];
int sentenceCurrentlyModified;


//SOUND
SoundManager sm;
int startTime;
int loop=0;
float bandHeightFR;
boolean isTransitioning = false;
boolean messageOn = false;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(1920, 1920);
  RG.init(this);
  f = new RFont("SFNSText.ttf", int( fontSize), LEFT);

  for (int i=0; i<message.length; i++) {
    characters[i]= new characterSpec( gShape[i], message[i]);
  }

  //SOUND
  sm= new SoundManager(this);
  indexPhraseFR = 0;
  indexPhraseSetFR = -1;
  // TIME
  startTime=millis();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void draw() {

  background(0);
  smooth();
  sm.update();

  translate(500, 100);

  for (int i=0; i<message.length; i++) {
    // println("i"+":"+i);

    translate(0, i+1*50);
    if (i%4==0) {
      translate(-80, 0);
    }
    if (i<3) {
      translate(i*20, 0);
    } else if (i==3) {
      translate(130, 0);
    } else if (i>3 && i<7) {
      translate(-280, 0);
      translate(i*45, 0);
    } else if (i==7) {
      translate(-150, 0);
    } else if (i==8) {
      translate(355, 0);
    } else if (i==9) {
      translate(-150, 0);
    } else if (i==10) {
      translate(200, 0);
    } else if (i>10 && i <12) {  
      translate(-160, 0);
    } else if (i==12) {
      translate(160, 0);
    } else if (i==13) {
      translate(-190, 0);
    }
    if (i<=8 && i%4==0) {
      translate(0, 40);
    }
    if (  i==11 ) {
      translate(0, 40);
    }

    if (sentenceCurrentlyModified==i) {
      characters[i].update(); 
    }
    if (sentenceCurrentlyModified>=i) {
      characters[i].display();
    }
  }
}

void initAttractorFR(int i, int j) { 
  attractorW= new WordAttractor(x, y, pointsP[i][j]);
}

void nextPhraseSetFR() {
}
void nextPhrase() {
  //println(phraseSet[indexPhraseSet][indexPhrase]);
}

class characterSpec {
  String  m;
  int tChildCount;
  RShape bShape;
  RShape letterShapes;

  characterSpec(RShape _letterShapes, String _m) {

    letterShapes=_letterShapes;
    //bShape=_bShape;
    m=_m;
    for (int i=0; i<m.length(); i++) {
      pointsP= new RPoint [m.length()][splitGlyph];

      listWordAttractors= new WordAttractor [m.length()][splitGlyph];
      listDistMap = new float [m.length()][splitGlyph];
      for (int n=0; n<m.length(); n++) {
        for (int j=0; j<splitGlyph; j++) {
          listDistMap[n][j]=100000;
        }
      }
      listPV = new PVector[m.length()][splitGlyph];
      //for (int l=0; l<m.length(); l++) {

      //println("m.length()"+":"+m.length());
      if (m.length()>0) {

        bShape= new RShape();
        bShape= f.toShape(m);
        RShape[]letterShapes = bShape.children;
        letterShapes = bShape.children;
        tChildCount = bShape.children.length;
        int child=bShape.children.length;
        child=max(0, bShape.children.length);
        child=tChildCount;
        //println("bShape.children.length"+":"+bShape.children.length);
      }
    }
  }

  void update() {

    for (int k=0; k<tChildCount; k++) {  
      float d= dist(attractorPosXFR, 0, bShape.children[k].getCenter().x, 0);
      float sx=map(d, 0, 75, 1.0, 1.05);

      if (d<75) {
        bShape.children[k].scale(sx, bShape.children[k].getCenter());
      }
      for (int j=0; j<splitGlyph; j++) {      
        float frac =(1.0/splitGlyph);
        pointsP[k][j]=bShape.children[k].getPoint(j*frac);
        float dist1 = dist(attractorPosXFR -200, attractorPosYFR +50, pointsP[k][j].x, pointsP[k][j].y);
        if (dist1 < listDistMap[k][j]) {
          //  On remplace toutes les distances possibles entre la souris et les points par la distance minimale
          listDistMap[k][j]=dist1;
          listPV[k][j]=new PVector(attractorPosXFR -200, attractorPosYFR +50);
          listWordAttractors[k][j]=new WordAttractor(listPV[k][j].x, listPV[k][j].y, pointsP[k][j]);
        }
        listWordAttractors[k][j].points = pointsP[k][j];
        listWordAttractors[k][j].attract(); 
        pushMatrix();
        if (m==",") {
          pointsP[k][j].x+=10*k;
        }
        popMatrix();
      }
    }
  }

  void display() {
    for (int k=0; k< tChildCount; k++) {
      for (int j=0; j<splitGlyph; j++) {

        float frac =(1.0/splitGlyph);
        pointsP[k][j]=bShape.children[k].getPoint(j*frac);
        float dist1 = dist(attractorPosXFR -200, attractorPosYFR +50, pointsP[k][j].x, pointsP[k][j].y);
        if (dist1 < listDistMap[k][j]) {
          //  On remplace toutes les distances possibles entre la souris et les points par la distance minimale
          listDistMap[k][j]=dist1;
          listPV[k][j]=new PVector(attractorPosXFR -200, attractorPosYFR +50);
          listWordAttractors[k][j]=new WordAttractor(listPV[k][j].x, listPV[k][j].y, pointsP[k][j]);
        }
        listWordAttractors[k][j].points = pointsP[k][j];

        pushMatrix();
        translate(pointsP[k][j].x, pointsP[k][j].y);
        beginShape();
        stroke(255);
        noFill();
        strokeWeight(0.5);
        float angle = TWO_PI/18;
        rotate(angle*j/4+noise(pointsP[k][j].x)/20);
        bezier(-3*(noise(5)), 3, -6*(noise(2)), 3, -4*noise(10), -3, 3, -3);
        endShape();
        popMatrix();

        if (k<=tChildCount) {
          pushMatrix();
          translate(pointsP[k][j].x, pointsP[k][j].y);
          RPoint attractorPosFR = new RPoint(attractorPosXFR, attractorPosYFR);
          attractorPosFR = new RPoint(attractorPosXFR+100, attractorPosYFR);
          float dist = pointsP[k][j].dist(attractorPosFR);
          if (dist<150) {
            dist = map(dist, 150, 0, 1, 0);
            if (attractorPosFR.x ==0) {
              stroke(255, 10) ;
            } else { 
              stroke(255, dist*255);
            }
            float angle_01 = TWO_PI*10;
            //rotate (j/angle*frameCount/10);
            rotate (j/angle_01*2);
            bezier(-2*(noise(10)), 10, 10*(noise(10)), -5, 2*noise(5), -10, 10, dist*attractorPosFR.x/20);//
          }
          popMatrix();
        }
      }
    }
  }
}


import ddf.minim.analysis.*;
import ddf.minim.*;


//variable 'public'
String []soundNamesFR = {"FR_01", "FR_02", "FR_03", "FR_04", "FR_05", "FR_06", "FR_07", "FR_08", "FR_09", "FR_10", "FR_11", "FR_12", "FR_13", "FR_14"};
float attractorPosXFR, attractorPosYFR;

class SoundManager {
  //SOUND
  Minim minim;
  AudioPlayer background;
  AudioPlayer[]soundsFR;
  FFT fftFR;
  float transitionTime = 0;
  int startTransitionTime;
  int transitionDuration = 1500;

  SoundManager(PApplet app) {

    minim = new Minim(app);
    background = minim.loadFile("WAR.wav");
    soundsFR = new AudioPlayer[soundNamesFR.length];
    for (int i =0; i<soundNamesFR.length; i++) {
      soundsFR[i] = minim.loadFile(soundNamesFR[i]+".wav", 512);
    }
  }

  void update() {

    if (isTransitioning) {
      if (millis() >= startTransitionTime+transitionDuration) {
        // transition end
        // si c'est pas fini on passe au suivant
        if (indexPhraseSetFR < soundsFR.length) {
          isTransitioning=false;
          transitionTime=0; 
          nextPhraseSetFR();
          playSound();

          // si on a lu tous les groupes on recommence à zero
        } else if (indexPhraseSetFR == soundsFR.length && millis() >= startTransitionTime+transitionDuration) {         
          // reset from the beginning 
          isTransitioning=false;
          transitionTime=0;    
          indexPhraseSetFR=0;
          indexPhraseFR=0;
          //nextPhraseSetFR();
          sentenceCurrentlyModified=0;
          background.shiftGain(-20, -80, 1000);
          background.rewind();
          background.pause();
          startTime = millis();
          playSound();
          background.play();
          background.shiftGain(-80, -20, 1000);
        }
      } else if (millis() <= startTransitionTime+transitionDuration) {       
        //  we are transiting 
        transitionTime = map(millis(), startTransitionTime, startTransitionTime+transitionDuration, 0., 1.);
      }
    } else {
      if ( indexPhraseSetFR==-1) { 
        // Initialise all
        sentenceCurrentlyModified=0;
        indexPhraseSetFR=0;
        indexPhraseFR=0;
        playSound();
        nextPhraseSetFR();
        background.play();
        background.shiftGain(-80, -20, 1000);
      } else if ( !soundsFR[indexPhraseFR].isPlaying()) {  
        // sound file is finished read next one
        indexPhraseFR++;
        sentenceCurrentlyModified++;
        sentenceCurrentlyModified=indexPhraseFR;
        println("indexPhraseFR"+":"+ indexPhraseFR);

        if ( isTransitioning==false && indexPhraseFR >= soundsFR.length) {
          // If phrases'index is greater than the stanza's index then go on to the next stanza
          indexPhraseFR=0;// 1rst sentence
          sentenceCurrentlyModified=0;
          //indexPhraseSetFR++;// increase stanza's index
          isTransitioning = true;
          startTransitionTime = millis();
        } else {
          //go to the next phrase   
          nextPhrase();
        
        }
        if (millis() >= startTransitionTime+transitionDuration) {
          playSound();
        }
      } else { 
        // we're reading the sound file
        // analyse of the sound
        soundFFTAnalyse();
        wordAttractorToSound();
      }
    }
  }


  void pauseSound() {
    AudioPlayer fr = soundsFR[indexPhraseFR];
    fr.rewind();
    fr.pause();
    fftFR = new FFT(fr.bufferSize(), fr.sampleRate());
  }

  void playSound() {
    AudioPlayer fr = soundsFR[indexPhraseFR];
    fr.rewind(); 
    fr.play();
    fftFR = new FFT(fr.bufferSize(), fr.sampleRate());
    attractorPosXFR = 0;
    attractorPosYFR =0;
    bandHeightFR = 0;
  }

  void soundFFTAnalyse() {
    AudioPlayer fr = soundsFR[indexPhraseFR];
    fftFR.forward(fr.mix);
    for (int i =0; i< fftFR.specSize(); i++) {
      float bandDBFR = 10*log(fftFR.getBand(i)/fftFR.timeSize());
      bandDBFR = constrain(bandDBFR, -1000, 1000);
      bandHeightFR = map(bandDBFR*4, 0, -220, 0, height);
    }
  }

  void wordAttractorToSound() {

    AudioPlayer fr = soundsFR[indexPhraseFR]; 
    initAttractorFR(indexPhraseSetFR, indexPhraseFR);
    attractorW= new WordAttractor(x, y, pointsP[i][j]);
    attractorPosXFR = map(fr.position(), 0, fr.length(), 100, width-1000);
    attractorPosYFR = bandHeightFR/8-350;
    attractorW.moveTo(attractorPosXFR, attractorPosYFR); 
    //attractorW.attract();
    //wAttractorFR.display();
  }
}

class WordAttractor {

  float force_radious =150;
  float maxForce = 15;
  RPoint position;
  RPoint points;
  float pX;
  float pY;

  WordAttractor(float x, float y, RPoint p) {
    points =p;
    position = new RPoint(x, y);
  }

  void attract() {

      float d= points.dist(position);
      if (d < force_radious) {   
        RPoint desired = new RPoint(points);
        desired.sub(position);
        desired.normalize();
        desired.scale(map(d, 0, force_radious, maxForce, 0));
        points.add(desired);   
    }
  }
  void moveTo(float x, float y) {
    position.x=x;
    position.y=y;
  }
}

I don’t understand

Does this run once or on and on?

Does it work the first time? And fails only the second time and onwards?

critical are the lines where you do update and display

Laurent Mareschal
https://laurentmareschal.com


P +33 (0)6.65.62.44.59

----- Mail d’origine -----

I don’t understand

Does this run once or on and on?

Does it work the first time? And fails only the second time and onwards?

Hey,
It runs on and on.

It works th 1rst time the attractor deforms the first sentence according to the 1rst sound.
But when the 2nd sound begins both the 1rst and 2nd sentences are deformed by the 2nd attractor and so on until the 13th and last sound so the 1rsts sentence is completely deformed because modified 13 times !! I would like that sound 1 deform sentence 1 then sound 2 deforms sentnce 2 only and so on.

I tried few options with the variable currentSentenceModified==i but did’nt manage that:

  • The sentences will appear one by one when we start to play a new sound file (actually this I did succeed)
  • Each sentence will be deformed by just one attractor at once
  • At the end the sound loop but the sentences are deformed and not rewritten from start…
    I hope I am clear enough?!
    Thank you so much for your help.
    Best, L
1 Like

Answered via PM

Chrisir

Dear @Chrisir ,

Thank you very much for the updated sketch you sent me, it’s great. But what should I do with the update_OLD() function?! Since now it works but no sentence is deformed by the attractor nor enlarged by the scale function:

bShape.children[k].scale(sx, bShape.children[k].getCenter());

??!!
When I uncomment update_OLD() it partially works : the scale function works but the attractor deforms the sentences before they appear?! It’s frustrating. Thanks a lot in advance. L

Update() wasn‘t in use anymore

The things were done in display()

In my version it changes the current of the sentences (the last one)

Oh yes, true! Update() wasn’t in use since I was looking for a way to separate update() and display() in draw() that they will act in different ways. Thank youvery much for your version where it changes the current of the last sentence, that’s what I was looking for but in link with the attractor that attract all the sentences!
Now the sentences appear one after the other, thanks to you, but the attractor still attracts all the sentences together and not only the last one… How can each attractor only attracts the last sentence ? When it loops also Scale doesn’t restart from scratch but from the last scale! How to reset scale each time we loop from the 1rst sentence?! Should I save the initial state to reverse it?
Sorry for being so demanding, I don’t find my way…Thanks for your great help.Best wishes, L

I just checked the last version I send you via e-mail (I send you only the pde files, so copy your last version and copy my pde files into it and run it).

The sentences appear one by one and only the last one gets changed by the Audio.

But the change is not permanent.

Dear @Chrisir,
Thank you for responding and for your patience.

The sentences appear one by one and only the last one gets changed by the Audio.

Yes the second bezier curves get changed by the audio and the change is not permanent, thi sis great and that’s what I wanted thank you very much.
But the other permanent changes produced by these functions :

  1. This one deforms the sentences: (in update() in characters tab)
listWordAttractors[k][j].points = pointsP[k][j];
 listWordAttractors[k][j].attract(); 

2 This one enlarged letters according to sound (in update() in characters tab):

float d= dist(attractorPosXFR, 0, bShape.children[k].getCenter().x, 0);
      float sx=map(d, 0, 75, 1.0, 1.05);

      if (d<75) {
        bShape.children[k].scale(sx, bShape.children[k].getCenter());
      }

don’t work properly. The 1rst function that deforms, deforms all the sentences instead of deforming one one by one and just the last sentence. The 2nd function that enlarges the letters does the job but doesn’t reset when loop from the 1rst sentence.I hope you can helpme to solve this problems?! Thanks a lot. Best, L

Can you send me the thing via email?

I assume you made
Changes?

Sorry,
I couldn’t send you anything before.
As usual I’ve sent you the files via wetransfer…
I’ve just made light changes to the sketch.
Hope it will help to solve the problem with the attractors!
Thank you so much @Chrisir!
Best wishes,

L

these lines are not activated in the code you sent me?

in function update these lines are not activated

BUT they are activated in the function display!!!

You copied part of update() into function display!!!

you changed the code… WHY!!!

PLEASE: do this: Should I save the initial state to reverse it?

I don’t have times, my apologies.

Chrisir

Dear Chrisir,

Oups, I ve sent you a wrong file, I apologize.
I’ll try to reverse scale function.
But I feel as if I harass you, since you are very busy.
Now I am late and I need the sketch to be done before the 21 rst of june!
Would you mind if I ask for some help to someone else on the forum?!
I am sorry to ask you that and to be unable to debug alone…
Thank you so much for your help.
Best wishes,
L

Okay

Please ask someone else

Dear Chrisir,

I tried to ask to someone else (out of the forum), but off course I haven’t found anyone else as competent and as patient as you are… I’ve decided not to show this sketch in the exhibition I was supposed to at the end of this week and to try to solve what appear to be the last problem in the sketch with your help if you want. I’ve cleaned up the sketch and managed to loop. But the attractor still attracts every points and not only the points of the selected line and I don’t find a way to solve this problem. I am really sorry I do my best… L

import processing.pdf.*;
import geomerative.*;
import ddf.minim.analysis.*;
import ddf.minim.*;

//TEXT
int indexPhraseSetFR;
int indexPhraseFR;
int x, y, i, j;
String []message={
  "On me dit de te haïr et je m'y efforce", 
  "Je t'imagine cruel, violent, implacable", 
  "mais à te voir je n'ai bientôt plus de force", 
  "et de te blesser je suis bien incapable", 

  "Tous mes camarades combattent avec rage", 
  "Et pleurent la nuit au souvenir des supplices", 
  "Infligés à leurs frères qui sont du même âge", 
  "et rêvent comme eux de toucher une peau lisse", 

  "Et de pouvoir enfin caresser des obus", 
  "Autres que ceux produits par le pouvoir obtus", 
  "Je rêve de quitter ces boyaux infernaux", 

  "De laisser ces furieux des deux bords du Rhin", 
  "Et de pouvoir embrasser ta chute de rein", 
  "Et porter notre amour sur les fonts baptismaux"
};

color textColor=0;
RFont f;
float fontSize=60;
int splitGlyph = 120;
RPoint[][] pointsP;
float r = random(5, 20);
WordAttractor attractorW;
// We create 3 new lists parallel to pointsP
// List of attractors, one per glyph
WordAttractor [][] listWordAttractors;
// List of all the distances between all the attractors and the pointsP
float [][] listDistMap;
// List of vectors to replace the pointsP coordinates
PVector [][] listPV;

RShape [] gShape = new RShape[message.length]; 
characterSpec [] characters= new characterSpec[message.length];
int sentenceCurrentlyModified;
boolean modifyThis;

//SOUND
SoundManager sm;
int startTime;
int loop=0;
float bandHeightFR;
boolean isTransitioning = false;
boolean messageOn = false;
String []soundNamesFR = {"FR_01", "FR_02", "FR_03", "FR_04", "FR_05", "FR_06", "FR_07", "FR_08", "FR_09", "FR_10", "FR_11", "FR_12", "FR_13", "FR_14"};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  size(1920, 1920);
  RG.init(this);
  f = new RFont("SFNSText.ttf", int( fontSize), LEFT);

  for (int i=0; i<message.length; i++) {
    characters[i]= new characterSpec( gShape[i], message[i]);
  }

  //SOUND
  sm= new SoundManager(this);
  indexPhraseFR = 0;
  indexPhraseSetFR = -1;
  // TIME
  startTime=millis();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void draw() {

  background(0);
  smooth();
  sm.update();

  translate(350, 100);

  for (int i=0; i<message.length; i++) {
    // println("i"+":"+i);

    translate(0, i+1*70);
    if (i%4==0) {
      translate(-80, 0);
    }
    if (i<3) {
      translate(i*20, 0);
    } else if (i==3) {
      translate(130, 0);
    } else if (i>3 && i<7) {
      translate(-280, 0);
      translate(i*45, 0);
    } else if (i==7) {
      translate(-150, 0);
    } else if (i==8) {
      translate(355, 0);
    } else if (i==9) {
      translate(-150, 0);
    } else if (i==10) {
      translate(200, 0);
    } else if (i>10 && i <12) {  
      translate(-160, 0);
    } else if (i==12) {
      translate(160, 0);
    } else if (i==13) {
      translate(-190, 0);
    }
    if (i<=8 && i%4==0) {
      translate(0, 40);
    }
    if (  i==11 ) {
      translate(0, 40);
    }

    if (sentenceCurrentlyModified==i) { 
      characters[i].update();
    }

    if (sentenceCurrentlyModified>=i) {
      characters[i].display((sentenceCurrentlyModified == i));
    }
  }
}

class characterSpec {
  String  m;
  int tChildCount;
  RShape bShape;
  RShape letterShapes;

  characterSpec(RShape _letterShapes, String _m) {

    letterShapes=_letterShapes;
    //bShape=_bShape;
    m=_m;
    //for (int i=0; i<m.length(); i++) {
    pointsP= new RPoint [m.length()][splitGlyph];

    listWordAttractors= new WordAttractor [m.length()][splitGlyph];
    listDistMap = new float [m.length()][splitGlyph];
    for (int n=0; n<m.length(); n++) {
      for (int j=0; j<splitGlyph; j++) {
        listDistMap[n][j]=100000;
      }
    }
    listPV = new PVector[m.length()][splitGlyph];

    if (m.length()>0) {
      bShape= new RShape();
      bShape= f.toShape(m);
      RShape[]letterShapes = bShape.children;
      letterShapes = bShape.children;
      tChildCount = bShape.children.length;
    }
  }

  void update() {

    for (int k=0; k<tChildCount; k++) {  

      float d= dist(attractorPosXFR, 0, bShape.children[k].getCenter().x, 0);
      float s=map(d, 0, 75, 1.0, 1.10);
      if (d<75) {
        bShape.children[k].scale(s, bShape.children[k].getCenter());
      }

      for (int j=0; j<splitGlyph; j++) { 
        float frac =(1.0/splitGlyph);
        pointsP[k][j]=bShape.children[k].getPoint(j*frac);

        float dist1 = dist(attractorPosXFR, attractorPosYFR, pointsP[k][j].x, pointsP[k][j].y);
        if (dist1 < listDistMap[k][j]) {
          //  On remplace toutes les distances possibles entre la souris et les points par la distance minimale
          listDistMap[k][j]=dist1;
          listPV[k][j]=new PVector(attractorPosXFR, attractorPosYFR);
          listWordAttractors[k][j]=new WordAttractor(listPV[k][j].x, listPV[k][j].y, pointsP[k][j]);
        }
        listWordAttractors[k][j].points=pointsP[k][j];
        listWordAttractors[k][j].attract();
        // to check out where is the attractor
        noStroke();
        fill(255, 0, 0);
        ellipse(attractorPosXFR, attractorPosYFR, 20, 20);
        pushMatrix();
        if (m==",") {
          pointsP[k][j].x+=10*k;
        }
        popMatrix();
      }
    }
  }

  void display(boolean modifyThis) {
    for (int k=0; k< tChildCount; k++) {
      for (int j=0; j<splitGlyph; j++) {  
        float frac =(1.0/splitGlyph);
        pointsP[k][j]=bShape.children[k].getPoint(j*frac);

        pushMatrix();
        translate(pointsP[k][j].x, pointsP[k][j].y);
        beginShape();
        stroke(255);
        noFill();
        strokeWeight(0.5);
        float angle = TWO_PI/18;
        rotate(angle*j/4+noise(pointsP[k][j].x)/20);
        bezier(-3*(noise(5)), 3, -6*(noise(2)), 3, -4*noise(10), -3, 3, -3);
        endShape();
        popMatrix();
        if (modifyThis) {
          if (k<=tChildCount) {
            pushMatrix();
            translate(pointsP[k][j].x, pointsP[k][j].y);
            RPoint attractorPosFR = new RPoint(attractorPosXFR, attractorPosYFR);
            attractorPosFR = new RPoint(attractorPosXFR+200, attractorPosYFR+50);
            float dist = pointsP[k][j].dist(attractorPosFR);
            if (dist<200) {
              dist = map(dist, 150, 0, 1, 0);
              if (attractorPosFR.x ==0) {
                stroke(255, 10) ;
              } else { 
                stroke(255, dist*255);
              }
              float angle_01 = TWO_PI*10;
              //rotate (j/angle*frameCount/10);
              rotate (j/angle_01*2);
              if (modifyThis) {
                bezier(-2*(noise(10)), 10, 10*(noise(10)), -5, 2*noise(5), -10, 10, dist*attractorPosFR.x/20);//
              } else {

                bezier(-2*(noise(10)), 10, 10*(noise(10)), -5, 2*noise(5), -10, 10, 1);//
              }
            }
            // print(".");
            popMatrix();
          }
        }
      }
    }
  }
}


import ddf.minim.analysis.*;
import ddf.minim.*;


//variable 'public'

float attractorPosXFR, attractorPosYFR;
float []linesYPositions1 ={10.,50., 90., 130., 250., 300., 350., 400.};
float []linesYPositions2 ={370., 520., 670.};


class SoundManager {
  //SOUND
  Minim minim;
  AudioPlayer background;
  AudioPlayer[]soundsFR;
  FFT fftFR;
  float transitionTime = 0;
  int startTransitionTime;
  int transitionDuration = 1500;

  SoundManager(PApplet app) {

    minim = new Minim(app);
    background = minim.loadFile("WAR.wav");
    soundsFR = new AudioPlayer[soundNamesFR.length];
    for (int i =0; i<soundNamesFR.length; i++) {
      soundsFR[i] = minim.loadFile(soundNamesFR[i]+".wav", 512);
    }
  }

  void update() {

    if (isTransitioning) {
      if (millis() >= startTransitionTime+transitionDuration) {
        // transition end
        // si c'est pas fini on passe au suivant
        if (indexPhraseSetFR < soundsFR.length) {
          isTransitioning=false;
          transitionTime=0; 
          //nextPhraseSetFR();
          playSound();

          // si on a lu tous les groupes on recommence à zero
        } else if (indexPhraseSetFR == soundsFR.length && millis() >= startTransitionTime+transitionDuration) {         
          // reset from the beginning 
          isTransitioning=false;
          transitionTime=0;    
          indexPhraseSetFR=0;
          indexPhraseFR=0;
          //nextPhraseSetFR();
          sentenceCurrentlyModified=0;
          background.shiftGain(-20, -80, 1000);
          background.rewind();
          background.pause();
          startTime = millis();
          playSound();
          background.play();
          background.shiftGain(-80, -20, 1000);
        }
      } else if (millis() <= startTransitionTime+transitionDuration) {       
        //  we are transiting 
        transitionTime = map(millis(), startTransitionTime, startTransitionTime+transitionDuration, 0., 1.);
        for (int i=0; i<message.length; i++) {
          characters[i]= new characterSpec( gShape[i], message[i]);
        }
      }
    } else {
      if ( indexPhraseSetFR==-1) { 
        // Initialise all
        sentenceCurrentlyModified=0;
        indexPhraseSetFR=0;
        indexPhraseFR=0;
        playSound();
        background.play();
        background.shiftGain(-80, -20, 1000);
      } else if ( !soundsFR[indexPhraseFR].isPlaying()) {  
        // sound file is finished read next one
        indexPhraseFR++;
        sentenceCurrentlyModified++;
        //sentenceCurrentlyModified=indexPhraseFR;

        if ( isTransitioning==false && indexPhraseFR >= soundsFR.length) {
          // If phrases'index is greater than the stanza's index then go on to the next stanza
          indexPhraseFR=0;// 1rst sentence
          sentenceCurrentlyModified=0;
          indexPhraseSetFR++;// increase stanza's index
          isTransitioning = true;
          startTransitionTime = millis();
        } else {
          //go to the next phrase   
          //nextPhrase();
        }
        if (millis() >= startTransitionTime+transitionDuration) {
          playSound();
        }
      } else { 
        // we're reading the sound file
        // analyse of the sound
        soundFFTAnalyse();
        wordAttractorToSound();
      }
    }
  }

  void pauseSound() {
    AudioPlayer fr = soundsFR[indexPhraseFR];
    fr.rewind();
    fr.pause();
    fftFR = new FFT(fr.bufferSize(), fr.sampleRate());
  }

  void playSound() {
    AudioPlayer fr = soundsFR[indexPhraseFR];
    fr.rewind(); 
    fr.play();
    fftFR = new FFT(fr.bufferSize(), fr.sampleRate());
    attractorPosXFR = 0;
    attractorPosYFR =indexPhraseFR*50;
    bandHeightFR = 0;
  }

  void soundFFTAnalyse() {
    AudioPlayer fr = soundsFR[indexPhraseFR];
    fftFR.forward(fr.mix);
    for (int i =0; i< fftFR.specSize(); i++) {
      float bandDBFR = 10*log(fftFR.getBand(i)/fftFR.timeSize());
      bandDBFR = constrain(bandDBFR, -1000, 1000);
      bandHeightFR = map(bandDBFR*4, 0, -220, 0, height);
    }
  }

  void wordAttractorToSound() {
    AudioPlayer fr = soundsFR[indexPhraseFR]; 
    attractorPosXFR = map(fr.position(), 0, fr.length(), 0, width-500);
    attractorPosYFR = indexPhraseFR*-10+bandHeightFR/8-350;
  }
}

class WordAttractor {

  float force_radious =200;
  float maxForce = 10;
  RPoint position;
  RPoint points;
  float pX;
  float pY;

  WordAttractor(float x, float y, RPoint p) {
    points =p;
    position = new RPoint(x, y);
  }

  void attract() {

      float d= points.dist(position);
      if (d < force_radious) {   
        RPoint desired = new RPoint(points);
        desired.sub(position);
        desired.normalize();
        desired.scale(map(d, 0, force_radious, maxForce, 0));
        points.add(desired);   
    }
  }
  void display () {
    translate( width/2,0);
    stroke(255,0,0);
    strokeWeight(10);
    ellipse (position.x, position.y, 30, 30);
  }
  void moveTo(float x, float y) {
    position.x=x;
    position.y=y;
  }
}

send me via email

Chrisir

okay thank you very much Chrisir I send it to you now…