# Sound and 3D surfaces

**URL:** https://discourse.processing.org/t/sound-and-3d-surfaces/30949
**Category:** Libraries
**Tags:** homework
**Created:** [June 28, 2021, 4:46pm UTC](https://discourse.processing.org/t/sound-and-3d-surfaces/30949 "2021-06-28T16:46:48Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![orbicularis](https://avatars.discourse-cdn.com/v4/letter/o/958977/32.png) [@orbicularis](https://discourse.processing.org/u/orbicularis)
#### Post date: [June 28, 2021, 4:46pm UTC](https://discourse.processing.org/t/sound-and-3d-surfaces/30949/1 "2021-06-28T16:46:48Z")

</div>

Hi,

I have a problem with these codes on Processing. I want to shape a 3d object with sound. There is no problem for shaping surfaces but it goes in loop. Do you know how to stop this? I need only one movement from bottom to top of the cylinder.

And I have also another problem. When I run the app, the cylinder is visible. How can I make it invisible at first? After each interaction with sound, it will be visible layer by layer from bottom to top, until end of the sound. Is it possible to do that?

I hope I can explain my two problems with Processing.  
Thank you for your help and advices.

````auto
import processing.dxf.*;

import ddf.minim.*;
Minim minim;
AudioInput in;

//import superCAD.*;
boolean saveOneFrame = false;
PVector [] thisrow;
PVector [] lastrow;

import peasy.*;
PeasyCam cam;
float buffSize;
float ang;
float angInc;
float rad = 1;
float amp = 200;
float zSpacing = 50; //layer size
boolean wireframe = false;

float numHeight = 50; // horizonal lines
float htRadInc = (TWO_PI*0)/numHeight;
float vaseRadScayl = 20;
PVector [][] points;
PVector [][] origpoints;
Quad [][] quads;

//ArrayList lines = new ArrayList();
//ArrayList tris = new ArrayList();
//ArrayList quads = new ArrayList();

void setup(){
 
 size(800, 800, P3D);
 
  
  //lights();
  minim = new Minim(this);
  
  // get a line in from Minim, default bit depth is 16
  in = minim.getLineIn(Minim.STEREO, 16);
  buffSize = in.bufferSize();
  cam = new PeasyCam(this,0,0,(numHeight*zSpacing/2), 500);
  thisrow = new PVector[int(buffSize)];
  lastrow = new PVector[int(buffSize)];
  points = new PVector[int(numHeight)][int(buffSize)];
  origpoints = new PVector[int(numHeight)][int(buffSize)];
  quads = new Quad[int(numHeight)][int(buffSize)];
  angInc = TWO_PI/buffSize;
  for(int i=0; i<numHeight; i++){
    rad = 500 + (vaseRadScayl*sin(i*htRadInc)); //radius size
    for (int j=0; j<buffSize; j++){
      ang = j*angInc;
      points[i][j] = new PVector(rad*cos(ang), rad*sin(ang), i*zSpacing);
      origpoints [i][j] = points[i][j];
    }
  }
  for(int i=0; i<numHeight-1; i++){
    for (int j=0; j<buffSize; j++){
      if(j<buffSize-1){
        quads[i][j] = new Quad(new PVector(i, j), new PVector(i,j+1), new PVector(i+1, j+1), new PVector(i+1, j));
      } else {
        quads[i][j] = new Quad(new PVector(i, j), new PVector(i,0), new PVector(i+1, 0), new PVector(i+1, j));
      }
    }
  }
}
boolean run = false;
float z=0;
int pindex = 0;

void draw(){
  background(255);
  frameRate(100);
  
  
  
  if(saveOneFrame == true) {
    String Dateobj = year() + "-" + month() + "-" + day() + "-" + hour() + "-" + minute() + "-" + second() + ".dxf";
    beginRaw(DXF, Dateobj);
  }
  //println(z);
  //stroke(255);
  // draw the waveforms
  for(int i = 0; i < buffSize; i++){
    ang = i*angInc;
    PVector p = new PVector(in.left.get(i)*amp*cos(ang) + origpoints[int(z/abs(zSpacing))][i].x, in.left.get(i)*amp*sin(ang) + origpoints[int(z/abs(zSpacing))][i].y, z);
    PVector pSound = new PVector(in.left.get(i)*amp*cos(ang), in.left.get(i)*amp*sin(ang), 0);
    thisrow[i] = p;
    if (run) {
      points[int(z/abs(zSpacing))][i].add(pSound);
    }
  }
  
  stroke(150);
  PVector p0, p1, p2, p3;
  
  for(int i=0; i<numHeight; i++){
    for (int j=0; j<buffSize; j++){
      if(i<numHeight-1){
        quads[i][j].render();
      }
    }
  }
  
  for(int i = 0; i < buffSize; i++){
    strokeWeight(2);
    
    stroke(0,255,0);
    if (i<buffSize-1){
      line(points[int(z/abs(zSpacing))][i].x, points[int(z/abs(zSpacing))][i].y, points[int(z/abs(zSpacing))][i].z, points[int(z/abs(zSpacing))][i+1].x, points[int(z/abs(zSpacing))][i+1].y, points[int(z/abs(zSpacing))][i+1].z);
    } else {
      line(points[int(z/abs(zSpacing))][i].x, points[int(z/abs(zSpacing))][i].y, points[int(z/abs(zSpacing))][i].z, points[int(z/abs(zSpacing))][0].x, points[int(z/abs(zSpacing))][0].y, points[int(z/abs(zSpacing))][0].z);
    }
    stroke(255,0,0);
    if (i<buffSize-1){
      line(thisrow[i].x, thisrow[i].y, thisrow[i].z, thisrow[i+1].x, thisrow[i+1].y, thisrow[i+1].z);
    } else {
      line(thisrow[i].x, thisrow[i].y, thisrow[i].z, thisrow[0].x, thisrow[0].y, thisrow[0].z);
    }
  }
  
// for (int i=0; i<quads.size(); i++){
// Quad q = (Quad) quads.get(i);
// q.render();
// }
  
  for (int i=0; i<buffSize; i++){
    lastrow[i] = thisrow[i];
  }
  z += zSpacing;
  if(frameCount%(numHeight-1) == 0){
    zSpacing *= -1;
  }
  
  
// if (run){
// cam.lookAt(buffSize/2,0,z, 250);
// z+=20;
// }
  
  //if (frameCount%5==0){
  // //println("save!");
  // String Date = year() + "-" + month() + "-" + day() + "-" + hour() + "-" + minute() + "-" + second() + ".tiff";
  // save(Date);
  //}
  
  if(saveOneFrame) {
    endRaw();
    saveOneFrame = false; 
  }
  
}

void keyPressed(){
  if (key == 'r'){
    run = !run;
    //println(run);
  }
  if (key == 's'){
    saveOneFrame = true;
  }
  if (key == 'w'){
    wireframe = !wireframe;
  }
}

void stop()
{
  // always close Minim audio classes when you are done with them
  in.close();
  minim.stop();
  super.stop();
}

class Triangle{
  PVector a;
  PVector b;
  PVector c;
  
  Triangle(PVector A, PVector B, PVector C){
    a = A;
    b = B;
    c = C;
  }
  
  void render(){
    beginShape(TRIANGLES);
    vertex(a.x, a.y, a.z);
    vertex(b.x, b.y, b.z);
    vertex(c.x, c.y, c.z);
    endShape();
  }
}

class Quad{
  PVector a;
  PVector b;
  PVector c;
  PVector d;
  
  Quad(PVector A, PVector B, PVector C, PVector D){
    a = A;
    b = B;
    c = C;
    d = D;
  }
  
  void render(){
    strokeWeight(1);
    stroke(50);
    if (wireframe){
      noFill();
    } else {
      fill(240);
    }
    beginShape(QUADS);
    vertex(points[int(a.x)][int(a.y)].x, points[int(a.x)][int(a.y)].y, points[int(a.x)][int(a.y)].z);
    vertex(points[int(b.x)][int(b.y)].x, points[int(b.x)][int(b.y)].y, points[int(b.x)][int(b.y)].z);
    vertex(points[int(c.x)][int(c.y)].x, points[int(c.x)][int(c.y)].y, points[int(c.x)][int(c.y)].z);
    vertex(points[int(d.x)][int(d.y)].x, points[int(d.x)][int(d.y)].y, points[int(d.x)][int(d.y)].z);
    endShape();
  }
}```
````

---

<div class="post-metadata">

### Author: ![micuat](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micuat/32/19407_2.png) [@micuat](https://discourse.processing.org/u/micuat)
#### Post date: [July 3, 2021, 11:05am UTC](https://discourse.processing.org/t/sound-and-3d-surfaces/30949/2 "2021-07-03T11:05:37Z")

</div>

> [@orbicularis](#):
>
> I have a problem with these codes on Processing. I want to shape a 3d object with sound. There is no problem for shaping surfaces but it goes in loop. Do you know how to stop this? I need only one movement from bottom to top of the cylinder.

I think it looks like a loop because you are trying to draw the waveform. What you get with `in.left.get(i)` is a sample at 1/44100 seconds of time (or something like that). It doesn’t represent the “loudness” that you perceive, but it fluctuates a lot, and that makes you think that is a loop. Run minim’s Basics/DrawWaveformAndLevel example to see how it looks like. What you can do is either 1) use FFT (checkout Analysis/FFT/SoundSpectrum, for example) or 2) make the sample size a bit bigger (say 128 or 1024) and average them and use that value instead.

> [@orbicularis](#):
>
> And I have also another problem. When I run the app, the cylinder is visible. How can I make it invisible at first? After each interaction with sound, it will be visible layer by layer from bottom to top, until end of the sound. Is it possible to do that?

I would recommend you to use a class instead of storing values in arrays like `thisrow`, `lastrow` etc. A class that contains information about the quad, last position of the quad, etc so the code would be much more readable. Then this class can contain information like color and alpha value to make it visible/invisible.
