Skip to content

Instantly share code, notes, and snippets.

@coreygo
Last active January 25, 2016 01:28
Show Gist options
  • Save coreygo/18863f378aac3d0f8706 to your computer and use it in GitHub Desktop.
Save coreygo/18863f378aac3d0f8706 to your computer and use it in GitHub Desktop.
Processing with Minim FFT/BeatDetection audio visualization. Modeled after Pink Floyd's Dark Side of the Moon album cover.
import ddf.minim.*;
import ddf.minim.analysis.*;
Minim minim;
AudioPlayer player;
AudioInput input;
BeatDetect beat;
FFT fft;
float x, y, w, h, xCenter, yCenter, bRadius;
float smoothing = 4;
int specSize;
void setup() {
size(1920, 1080, P2D);
smooth(8);
frameRate(120);
// bug: required for proper alpha opacity layering
hint(DISABLE_OPTIMIZED_STROKE);
// always start Minim first
minim = new Minim(this);
// 1024 is the default length of the sample buffers
player = minim.loadFile("DarkSide.mp3", 1024);
input = minim.getLineIn();
fft = new FFT(player.bufferSize(), player.sampleRate());
specSize = fft.specSize();
beat = new BeatDetect();
bRadius = 100;
colorMode(HSB, specSize, 255, 255);
}
void draw() {
w = width;
h = height;
xCenter = w/2;
yCenter = h/2;
// waveform to light spectrum
fft.forward(player.mix);
background(0, 0, 10);
// bottom
outsidePrism();
fftEllipse();
beatEllipse();
fftLines();
prism();
prismVertex();
// top
}
void outsidePrism() {
for (int i = 0; i < specSize - 1; i++)
{
strokeWeight(2);
stroke(255, 10);
line(-1+i, 770 + player.mix.get(i)*100, 894, 528);
stroke(i, 255, 255, 2);
line(lerp(1000, 1034, .5), lerp(502, 560, .5), 1921, lerp(632, 784, .5)+i+player.mix.get(i)*200);
stroke(i, 255, 255, 4);
line(1000, 502, 1921, 632+i+player.left.get(i)*100);
line(1034, 560, 1921, 784+i+player.right.get(i)*100);
}
}
void prism() {
fill(40, 255);
strokeCap(ROUND);
strokeWeight(6);
stroke(255, 255);
// leftX,Y, topX,Y, rightX,Y
triangle(810, 670, 960, 410, 1110, 670);
}
void prismVertex() {
noStroke();
beginShape();
fill(255);
vertex(892, 528); // leftX,Y
fill(40);
vertex(1000, 500); // topX,Y
fill(40);
vertex(1034, 566); // rightX,Y
endShape();
}
void fftLines() {
for (int i = 0; i < specSize; i++)
{
float bandDB = 2 * log(2 * fft.getBand(i) / fft.timeSize());
float bandHeight = map(bandDB, 0, -150, 0, height/8);
fft.scaleBand(i, 0.5);
strokeWeight(4);
stroke(i, 255, 255, 40);
line(width/2+i+1, height/4 + fft.getBand(i)*bandHeight, width/2+i+1, height/4 - fft.getBand(i)*bandHeight);
line(width/2-i-1, height/4 + fft.getBand(i)*bandHeight, width/2-i-1, height/4 - fft.getBand(i)*bandHeight);
}
}
void fftEllipse() {
for (int i = 0; i <= 255; i++)
{
strokeWeight(1);
stroke(255, 127);
fill(0, 255);
ellipse(width/2, height/4, 1+player.mix.get(i)*360, 1+player.mix.get(i)*360);
}
}
void beatEllipse() {
beat.detect(player.mix);
fill(255, 127);
if (beat.isOnset()) bRadius = 200;
ellipse(width/2, height/4, bRadius, bRadius);
bRadius *= 0.8;
if (bRadius < 60) bRadius = 60;
}
void keyPressed()
{
if (player.isPlaying())
{
player.pause();
} else
{
player.loop();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment