Inspired by Coding Challenge: 3D Terrain Generation with Perlin Noise I would like to create an audio visualizer that display several successive audio frames as a terrain. I managed to create a basic working sketch but I can’t go further on achieving a proper display of the waveform. Yellow is the current stored wave frame and the terrain is the history of previously stored wave frames.
I assume the problem here is that the terrain does not have enough resolution for displaying waveforms. Can someone point me some solutions or alternatives visualizations? Any other idea on how to display the “history” of the stored audio frames in 3D?
Here is my code:
import processing.sound.*;
SoundFile sample;
Waveform waveform;
int scl = 20;
int w = 1200;
int h = 900;
int cols = w / scl;
int rows = h / scl;
float time = 0;
float [][] terrain;
int audioCols, audioRows;
float waveHist[][] = new float[cols][rows];
public void setup() {
size(600, 600, P3D);
terrain = new float[cols][rows];
sample = new SoundFile(this, "beat.aiff");
sample.loop();
waveform = new Waveform(this, cols);
waveform.input(sample);
for (int y=0; y<rows; y++) {
for (int x=0; x<cols; x++) {
waveHist[x][y] = 0;
}
}
}
public void draw() {
waveform.analyze(); //read the audio data
// fill the current row
int counter = frameCount % rows; // stores waveforms
for (int i = 0; i < cols; i++) {
waveHist[i][counter] = waveform.data[i];
}
time -= 0.1;
float yoff = time;
for (int y=0; y<rows; y++) {
float xoff=0;
for (int x=0; x<cols; x++) {
//terrain[x][y] = map(noise(xoff, yoff), 0, 1, -100, 100);
terrain[x][y] = map(waveHist[x][y],-1,1,-200,200);
xoff += 0.1;
}
yoff += 0.1;
}
// Set background color, noFill and stroke style
background(0);
stroke(255, 255, 0);
strokeWeight(2);
noFill();
//------------------------------------ 2d waveform
beginShape();
for (int i = 0; i < cols; i++) {
// Draw current data of the waveform
// Each sample in the data array is between -1 and +1
vertex(
map(i, 0, cols, 0, width),
map(waveform.data[i], -1, 1, 0, height) -200
);
}
endShape();
stroke(255);
//------------------------------ terrain
translate(width/2, height/2);
rotateX(PI/3);
//rotateZ(-PI/3);
translate(-w/2, -h/2);
for (int y=0; y<rows-1; y++) {
beginShape(TRIANGLE_STRIP);
for (int x=0; x<cols; x++) {
vertex(x*scl, y*scl, terrain[x][y]);
vertex(x*scl, (y+1)*scl, terrain[x][y+1]);
}
endShape();
}
}
The refresh rate is also pretty slow compared with the youtube video tutorial, so I assume I am doing something wrong and messed up…
Thanks a lot!!!