Last active
January 25, 2016 01:28
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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