import ddf.minim.analysis.*;
import ddf.minim.*;
// Declare and construct four objects
Minim minim;
AudioPlayer test;
FFT fft;
// These are elements of the 2D array.
int cols, rows;
int scl = 30;
// These are width and height of the terrain.
int w = 2000;
int h = 1600;
// Declare a 2D array
float[][] terrain;
void setup() {
size(1280, 720, P3D);
// Draws all geometry with smooth (anti-aliased) edges at level two
smooth(2);
// Initialize the object
minim = new Minim(this);
// Specify that we want the audio buffers of the AudioPlayer
// to be 1024 samples long because our FFT needs to have
// a power-of-two buffer size and this is a good size.
test = minim.loadFile("final.mp3", 1024);
// Create an FFT object that has a time-domain buffer
// the same size as test's sample buffer
// Note that this needs to be a power of two
// and that it means the size of the spectrum will be half as large.
fft = new FFT(test.bufferSize(), test.sampleRate());
// Play the song
test.play();
// Initialize each unit of the terrain
cols = w / scl;
rows = h / scl;
// Initialize the array
terrain = new float[cols][rows];
}
void draw() {
// Perform a forward FFT on the samples in test's mix buffer,
// which contains the mix of both the left and right channels of the file
fft.forward(test.mix);
// Re-maps the movement according to the amplitude of the requested frequency band 7
float yoff = map(fft.getBand(7), 0, 100, -2, 0);
// Re-maps the transparency according to the amplitude of the requested frequency band 7
float alpha = map(fft.getBand(7), 0, 100, 50, 255);
// Store the grid and the movement in a 2D array
for (int y = 0; y < rows; y++) {
// Re-maps the movement according to the amplitude of the requested frequency band 7
float xd = map(fft.getBand(7), 0, 100, -100, 100);
for (int x = 0; x < cols; x++) {
// Re-maps the movement and smooth each unit
terrain[x][y] = map(noise(xd, yoff), 0, 1, -200, 200);
// Increase the movement each time
xd += 0.2;
}
yoff += 0.2;
}
// Clean the background in order to present new patterns
background(0);
stroke(255, alpha);
noFill();
// Reset the initial point a bit higher than the center
translate(width / 2, height / 2 - 100);
// Rotate the floor to better see the patterns
rotateX(PI / 4);
// Reset the grid to display the pattern on the canvas
translate(-w / 2, -h / 2);
// Draw points and connect them together
// Note: the last row is deleted in order to avoid overflow
for (int y = 0; y < rows-1; y++) {
beginShape();
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();
}
}