Playing with sound wave

various types of viewing and scene output :
simple sound viewer

import processing.sound.*;
/////////////////////////////
AudioIn input;
Waveform waveform;
//////////////////////
int NCampioni;
float[]   punti ;
ArrayList<onda> onde ;
int valoriX;
int mode=0;
int   TipoOnda  =0;
boolean tralazione;
boolean tralazioneFinita;
int TipoEffeto;
int modeNuovo;
PGraphics pg;
//////////////////////////
Timer timer;
////////////////////////////
void setup()
{
  size(600, 600, P3D);
  ////////////////////////////////
  pg = createGraphics(width, height, P3D);
  NCampioni=50;
  valoriX=width/NCampioni;
  punti = new float[NCampioni];
  onde= new ArrayList<onda>();
  tralazione=false;
  tralazioneFinita=false;
  /////////////////////////
  input = new AudioIn(this, 0);
  input.start();
  /////////////////////////////////////
  waveform = new Waveform(this, NCampioni);
  waveform.input(input);
  /////////////////////////
  timer = new Timer(2000);
  timer.start();
  ///////////////////////////////////////
}

void draw()
{

  if (  timer.isFinished())
  {
    tralazione=true;
    timer = new Timer(2000);
    timer.start();
    TipoOnda=int(random(0, 8));
    mode=int(random(0, 3));
    //  mode=2;
    println(TipoOnda+" tipoonda "+mode +" mode");
    onde.clear();
  }
  waveform.analyze();
  float somma=0;

  for (int i = 0; i < punti.length; i++)//fiore
  {
    punti [i]=  waveform.data[i];
    somma+= punti [i];
  }
  pg.beginDraw();
  pg.background(0);
  onda temp = new onda(punti, TipoOnda, mode, somma);
  onde.add(temp);
  for (int i = 0; i < onde.size(); i++) {
    onda temp1=onde.get(i);
    temp1.update();
    temp1.display();
    if ( temp1.finished()) {
      onde.remove(i);
    }
  }

  {
  }
  pg.endDraw();
  image(pg, 0, 0);
}

class onda:

class onda {
  // Dati
  color colore ;
  PShape s;
  int red, blue, green, alpha, TipoOnda, mode, life;
  float[]   punti ;
  float indiceRotazione;
  boolean ifFill=false;
  //////////////////////////////////// // Constructor
  onda( float[] puntior, int TipoOndaR, int modeR, float somma) { 
    this.punti = puntior; 
    TipoOnda=TipoOndaR;
    mode=modeR;
    indiceRotazione=random(-1, 1);
    life=1;
    red=(255*(int(random(0, 2))));
    green=(255*(int(random(0, 2))));
    blue=(255*(int(random(0, 2))));
    alpha=255;
    s = createShape();

    switch(TipoOnda) {
    case 0: ///////////linea orr
      s.beginShape();
      s.noFill();
      for (int i=0; i <punti.length-1; i++)
      {         
        s.vertex  
          (
          map(i, 0, NCampioni, 0, width), 
          map(punti[i], -1, 1, 0, height), 
          0);
      }
      s.endShape();
      break;
    case 1: //////cerchio
      float angolo=0;
      s.beginShape();
      s.noFill();
      float raggio= width/3;
      for (int i=0; i <punti.length-1; i=i+2)
      {   
        angolo=(map(i, 0, NCampioni, 0, TWO_PI));

        s.vertex
          (
          sin(angolo)*raggio+(punti[i+1]*raggio/2)+width/2, 
          cos(angolo)*raggio+(punti[i]  *raggio/2)+height/2, 
          0);
      }
      s.endShape(CLOSE); 
      break;
    case 2: //////fiore
      if (mode==2) { 
        mode=1;
      }
      s.beginShape();
      s.noFill();
      for (int i=0; i <punti.length-1; i++)
      {   
        s.vertex(width/2, height/2, 0);
        s.vertex
          (      
          map(i, 0, NCampioni, width/2-width/3, width/2+width/3), 
          map(punti[i], -1, 1, height/2-height/3, height/2+ height/3), 
          0);
      }
      s.endShape(); 
      break;
    case 3: ///////////fuoco
      if (mode==2) { 
        mode=1;
      }
      s.beginShape();
      s.noFill();
      for (int i=0; i <punti.length-1; i++)
      {         
        s.vertex  
          (
          width/2, 
          height/2, 
          0);
        s.vertex  
          (
          map(punti[i], -1, 1, width/2-width/4, width/2+width/4 ), 
          map(i, 0, NCampioni, 0, height/2), 
          0);
      }
      s.endShape(); 
      break;
    case 4: ///////////lava
      mode=1;
      s.beginShape();
      beginShape(LINES);
      s.noFill();
      for (int i=0; i <punti.length-1; i++)
      {         
        s.vertex  
          (
          map(i, 0, NCampioni, 0, width), 
          0, 
          0);
        s.vertex  
          (
          map(i, 0, NCampioni, 0, width), 
          map(punti[i], -1, 1, 0, height), 
          0);
      }
      s.endShape(); 
      break;
    case 5: ///////////caso 1 fill
      ifFill=true;
      s.beginShape();
      s.fill(red, green, blue, alpha);
      for (int i=0; i <punti.length-1; i++)
      {         
        s.vertex  
          (
          map(i, 0, NCampioni, 0, width), 
          map(punti[i], -1, 1, 0, height), 
          0);
      }
      s.endShape();
      break;
    case 6: //////caso 1fill

      raggio= (width/4)*sin(somma);
      angolo=0;
      ifFill=true;
      color c=color(red, green, blue, alpha);
      s.setFill(c);
      s.beginShape();
      s.strokeWeight(somma*3);
      for (int i=0; i <punti.length-1; i=i+2)
      {   
        angolo=(map(i, 0, NCampioni, 0, TWO_PI));

        s.vertex
          (
          sin(angolo)*raggio+(punti[i+1]*raggio/2)+width/2, 
          cos(angolo)*raggio+(punti[i]  *raggio/2)+height/2, 
          0);
      }
      s.endShape(CLOSE); 
      break;
    case 7: //////caso fiore
                ifFill=true;
      s.beginShape();
      c=color(red, green, blue, alpha);
      s.setFill(c);
      for (int i=0; i <punti.length-1; i=i+2)
      {   
        raggio=(map(punti[i], -1, 1, width, width/1.5));
        angolo=(map(i, 0, NCampioni, 0, TWO_PI));
        s.vertex
          (
          sin(angolo)*raggio*(punti[i])+width/2, 
          cos(angolo)*raggio*(punti[i])+height/2, 
          0);
      }
      s.endShape(CLOSE); 
      break;
       case 8: //////caso sole
      s.beginShape();
      for (int i=0; i <punti.length-1; i=i+2)
      {   
        raggio=(map(punti[i], -1, 1, width, width/1.5));
        angolo=(map(i, 0, NCampioni, 0, TWO_PI));
         s.vertex(width/2,height/2,0);
        s.vertex
          (
          sin(angolo)*raggio*(punti[i])+width/2, 
          cos(angolo)*raggio*(punti[i])+height/2, 
          0);
      }
      s.endShape(); 
      break;
    }
  }
  ////////////////////////////////////metodi
  void display() {
    if (ifFill==true) {
      color c=color(red, green, blue, alpha);
      s.setFill(c);
    }
    s.setStroke(color(red, green,blue, alpha));
    shape(s);
  }
  ///////////////////////////////////////
  void update() {
    life++;
    alpha=alpha-(life*3);
    switch(mode) {
    case 0:  
      s.translate(-width/2, - height/2);
      s.rotateX(indiceRotazione);  
      s.translate(width/2, height/2);
      break;
    case 1:
      s.translate(0, life*indiceRotazione*2, 0);
      break;
    case 2:
      s.translate(-width/2, - height/2);
      s.translate(0, 0, life);  
      s.translate(width/2, height/2);
      break;
    }
  }
  /////////////////////////////////////////////
  boolean finished() {
    if (alpha < 0) {
      return true;
    } else {
      return false;
    }
  }
}

Daniel Shiffman’s timer:

class Timer {

  int savedTime; // When Timer started
  int totalTime; // How long Timer should last
  Timer(int tempTotalTime) {
    totalTime = tempTotalTime;
  }

  void setTime(int t) {
    totalTime = t;
  }

  // Starting the timer
  void start() {
    // When the timer starts it stores the current time in milliseconds.
    savedTime = millis();
  }

  // The function isFinished() returns true if 5,000 ms have passed. 
  // The work of the timer is farmed out to this method.
  boolean isFinished() { 
    // Check how much time has passed
    int passedTime = millis()- savedTime;
    if (passedTime > totalTime) {
      return true;
    } else {
      return false;
    }
  }
}
2 Likes

now I’m looking for a method to switch from one animation to another, is a slider between two pshape feasible?

1 Like

PShapes are usually very difficult to edit and update – they are made to generate once, then regenerate if you need them to change. To tween between two PShapes with the same list of ordered vertices, a good general approach is:

  • make PShape a (source)
  • make PShape b (target)
  • On a tween frame while animating between the two shapes, display a new shape that is generated just-in-time by a special function / method:
shape(tweenShapes(a, b, amt);

// ....

// (pseudocode, untested):
PShape tweenShapes(PShape a, PShape b, float amt) {
  PShape s = createShape();
  s.beginShape();
  for(int i=0; i< a.getVertexCount(), i++) {
    PVector v = PVector.lerp(a.getVertex(i), b.getVertex(i), amt);
    s.vertex(v.x, v.y);
  s.endShape();
  return s;
}

…or you could just cross-fade, like cross-fading video, if you don’t need a geometric transition.