Created
May 9, 2013 06:05
-
-
Save brianreavis/5545845 to your computer and use it in GitHub Desktop.
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 processing.video.*; | |
import processing.opengl.*; | |
import ddf.minim.*; | |
import ddf.minim.signals.*; | |
import ddf.minim.analysis.*; | |
import ddf.minim.effects.*; | |
MovieMaker mm; | |
ArrayList particles; | |
Minim minim; | |
AudioPlayer song; | |
BeatDetect beat; | |
FFT fft; | |
float vol, vol_low, vol_mid, vol_high; | |
int rangeMax = 25; | |
int ms_frame; | |
// ------------------------------ | |
class Particle { | |
Particle parent; | |
PVector loc; | |
float energy = 0; | |
float mass = 1; | |
float theta = 0; | |
float speed = 1; | |
int age = 0; | |
int lifetime = -1; | |
int spawnwait = 0; | |
void spawn() { | |
float t0 = random(0, TWO_PI); | |
int n = (int)random(4, 6); | |
for (int i = 0; i < n; i++) { | |
Particle particle = new Particle(); | |
particle.mass = mass * 0.6; | |
particle.parent = this; | |
int r = 2; | |
float t = t0 + TWO_PI * (i / (float)(n + 1)) + random(-0.1, 0.1); | |
particle.speed = vol_low * mass + 1; | |
particle.theta = t; | |
particle.lifetime = 10; | |
particle.loc = new PVector(loc.x + cos(t)*r, loc.y + sin(t)*r); | |
particles.add(particle); | |
} | |
spawnwait = 50; | |
} | |
void render() { | |
age++; | |
spawnwait--; | |
if (lifetime != -1 && age > lifetime) return; | |
if (vol_low > 1.1 && energy > 4 && spawnwait <= 0 && mass > 4) { | |
spawn(); | |
} | |
if (loc.x > width) loc.x = 0; | |
if (loc.y > height) loc.y = 0; | |
if (loc.x < 0) loc.x = width; | |
if (loc.y < 0) loc.y = height; | |
speed += energy; | |
PVector velo = new PVector(cos(theta)*speed, sin(theta)*speed); | |
loc.add(velo); | |
speed *= 0.8 + ((11 - mass) / 10) / 5; | |
speed = constrain(speed, 0, 100); | |
if (parent == null) { | |
theta += speed * 0.2 * (10 - mass) / 10 * (mass - 5) / 10; | |
} | |
fill(mass < 5 | |
? lerpColor(#00e1ff, #ffac00, energy / 6) | |
: lerpColor(#00e1ff, #ffac00, mass/10.0)); | |
float coeff_center = pow((height/2 - dist(loc.x, loc.y, width/2, height/2)) / (height/2.0), 2); | |
float r = coeff_center * energy * (pow(mass, 2)/2 + 1) * 2 * (0.4 + vol_low*2) + 2; | |
if (parent == null) { | |
r += pow(vol_low * mass / 10.0, 2)*10; | |
} | |
if (parent != null) { | |
fill(lerpColor(#ffec00, #ffc500, vol_mid), 250); | |
r = 10 * constrain((lifetime - age) / (float) lifetime, 0, 1) + 1; | |
} | |
ellipse(loc.x, loc.y, r, r); | |
fill(#0e1314); | |
if (parent == null) { | |
float rcoeff = 0.8; | |
ellipse(loc.x, loc.y, r * rcoeff, r * rcoeff); | |
} | |
} | |
} | |
// ------------------------------ | |
void setup() { | |
size(1280, 720); | |
frameRate(25); | |
smooth(); | |
mm = new MovieMaker(this, width, height, "render.mov", 25, MovieMaker.ANIMATION, MovieMaker.HIGH); | |
ms_frame = 1000 / 25; | |
minim = new Minim(this); | |
song = minim.loadFile("music.mp3", 1024); | |
song.play(); | |
beat = new BeatDetect(song.bufferSize(), song.sampleRate()); | |
beat.setSensitivity(500); | |
fft = new FFT(song.bufferSize(), song.sampleRate()); | |
initEnv(); | |
} | |
void initEnv() { | |
particles = new ArrayList(); | |
for (int i = 0; i < 150; i++) { | |
Particle particle = new Particle(); | |
particle.mass = random(1, 10); | |
particle.theta = random(0, TWO_PI); | |
particle.loc = new PVector(random(0, width), random(0, height)); | |
particles.add(particle); | |
} | |
} | |
// ------------------------------ | |
int t_lastFrame; | |
void draw() { | |
noStroke(); | |
background(#0e1314); | |
beat.detect(song.mix); | |
fft.forward(song.mix); | |
vol = 0; | |
vol_low = 0; | |
vol_mid = 0; | |
vol_high = 0; | |
int s = fft.specSize(); | |
int s_band = s / 4; | |
for (int i = 0; i < s; i++) { | |
float v = fft.getBand(i); | |
if (i < s_band) vol_low += v; | |
else if (i < s_band * 2) vol_mid += v; | |
else vol_high += v; | |
vol += v; | |
} | |
vol_low /= 1000.0; | |
vol_mid /= 1000.0; | |
vol_high /= 1000.0; | |
vol /= 1500.0; | |
noStroke(); | |
boolean beatBin[] = new boolean[10]; | |
for (int j = 0; j < beatBin.length; j++) { | |
beatBin[j] = beat.isOnset(j); | |
} | |
for (int i = 0, n = particles.size(); i < n; i++) { | |
Particle particle = (Particle)particles.get(i); | |
boolean hasBeat = beatBin[constrain(round(particle.mass), 0, 9)]; | |
float vp = (particle.mass < 5) ? vol_high / 2 : vol_low; | |
if (hasBeat) particle.energy += vp * 4; | |
particle.energy = max(0, particle.energy * 0.8); | |
particle.render(); | |
} | |
mm.addFrame(); | |
song.play(ms_frame * frameCount); | |
} | |
void keyPressed() { | |
if (key == ' ') { | |
mm.finish(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment