Created
May 27, 2014 18:36
-
-
Save punietis/d18114868ae2b355f8c3 to your computer and use it in GitHub Desktop.
Audio/Music Visualizer
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
//State Machine code by Natalie Freed from https://gist.github.com/nataliefreed/bee92f0b92ff888916cc | |
//http://www.pfesto.com/how-to-make-an-audio-visualizer-with-processing/ | |
import ddf.minim.*; | |
import ddf.minim.analysis.*; | |
Minim minim; | |
AudioPlayer song; | |
AudioMetaData meta; | |
FFT fft; | |
String currentState = "OFF"; | |
boolean keyLeft = false; | |
boolean keyRight = false; | |
boolean frequencySpectrum = false; | |
boolean waveform = false; | |
boolean lineVisualizer = false; | |
boolean circleVisualizer = false; | |
boolean dancingOctopus = false; | |
boolean paused = false; | |
boolean description = true; | |
boolean instructions = true; | |
float[] arrayi = new float[1024]; | |
void setup() | |
{ | |
size(800, 600); | |
minim = new Minim(this); | |
//m4a and mp4 files are not supported | |
//use online converters to change these to mp3 | |
song = minim.loadFile("07 Transcendence.mp3"); | |
song.play(); | |
meta = song.getMetaData(); | |
fft = new FFT(song.bufferSize(), song.sampleRate()); | |
textSize(10); | |
fill(0); | |
background(255); | |
} | |
void draw() | |
{ | |
background(255); | |
frameRate(60); | |
String currentEvent = checkForEvents(); | |
//changes events | |
if (currentEvent.length() > 0) | |
{ | |
currentState = transition(currentState, currentEvent); | |
} | |
//uses booleans to run functions | |
if (frequencySpectrum) | |
{ | |
frequencySpectrum(); | |
} | |
if (waveform) | |
{ | |
waveform(); | |
} | |
if (lineVisualizer) | |
{ | |
lineVisualizer(); | |
} | |
if (circleVisualizer) | |
{ | |
circleVisualizer(); | |
} | |
if (dancingOctopus) | |
{ | |
dancingOctopus(); | |
} | |
if (description) | |
{ | |
textAlign(LEFT); | |
textSize(10); | |
text("Title: " + meta.title(), 5, 10); | |
text("Artist: " + meta.author(), 5, 25); | |
text("Album: " + meta.album(), 5, 40); | |
} | |
if (instructions) | |
{ | |
textAlign(CENTER); | |
textSize(25); | |
text("Instructions:", 400, 265); | |
text("Use the left and right arrow keys to switch between visualizers", 400, 300); | |
text("Space pauses or plays the song", 400, 335); | |
text("Press 'd' to show or hide the song description", 400, 370); | |
text("Press 'i' to show or hide these instructions after this screen", 400, 405); | |
} | |
} | |
//checks to see if the right or left keys were pressed and returns events | |
String checkForEvents() | |
{ | |
String event = ""; | |
if (keyLeft) | |
{ | |
event = "LEFT KEY PRESSED"; | |
} | |
else if (keyRight) | |
{ | |
event = "RIGHT KEY PRESSED"; | |
} | |
return event; | |
} | |
//changes between states | |
String transition(String state, String event) | |
{ | |
if (state.equals("OFF")) | |
{ | |
if (event.equals("LEFT KEY PRESSED")) | |
{ | |
state = "FREQUENCY SPECTRUM"; | |
frequencySpectrum = true; | |
println("FREQUENCY SPECTRUM"); | |
} | |
else if (event.equals("RIGHT KEY PRESSED")) | |
{ | |
state = "CIRCLE VISUALIZER"; | |
circleVisualizer = true; | |
println("CIRCLE VISUALIZER"); | |
} | |
} | |
else if (state.equals("FREQUENCY SPECTRUM")) | |
{ | |
if (event.equals("LEFT KEY PRESSED")) | |
{ | |
waveform = true; | |
frequencySpectrum = false; | |
state = "WAVEFORM"; | |
} | |
else if (event.equals("RIGHT KEY PRESSED")) | |
{ | |
circleVisualizer = true; | |
frequencySpectrum = false; | |
state = "CIRCLE VISUALIZER"; | |
} | |
} | |
else if (state.equals("CIRCLE VISUALIZER")) | |
{ | |
if (event.equals("LEFT KEY PRESSED")) | |
{ | |
frequencySpectrum = true; | |
circleVisualizer = false; | |
state = "FREQUENCY SPECTRUM"; | |
} | |
else if (event.equals("RIGHT KEY PRESSED")) | |
{ | |
lineVisualizer = true; | |
circleVisualizer = false; | |
state = "LINE VISUALIZER"; | |
} | |
} | |
else if (state.equals("LINE VISUALIZER")) | |
{ | |
if (event.equals("LEFT KEY PRESSED")) | |
{ | |
circleVisualizer = true; | |
lineVisualizer = false; | |
state = "CIRCLE VISUALIZER"; | |
} | |
else if (event.equals("RIGHT KEY PRESSED")) | |
{ | |
dancingOctopus = true; | |
lineVisualizer = false; | |
state = "DANCING OCTOPUS"; | |
} | |
} | |
else if (state.equals("DANCING OCTOPUS")) | |
{ | |
if (event.equals("LEFT KEY PRESSED")) | |
{ | |
lineVisualizer = true; | |
dancingOctopus = false; | |
state = "LINE VISUALIZER"; | |
} | |
else if (event.equals("RIGHT KEY PRESSED")) | |
{ | |
waveform = true; | |
dancingOctopus = false; | |
state = "WAVEFORM"; | |
} | |
} | |
else if (state.equals("WAVEFORM")) | |
{ | |
if (event.equals("LEFT KEY PRESSED")) | |
{ | |
dancingOctopus = true; | |
waveform = false; | |
state = "DANCING OCTOPUS"; | |
} | |
else if (event.equals("RIGHT KEY PRESSED")) | |
{ | |
frequencySpectrum = true; | |
waveform = false; | |
state = "FREQUENCY SPECTRUM"; | |
} | |
} | |
resetEvents(); | |
return state; | |
} | |
//Frequency Spectrum | |
void frequencySpectrum() | |
{ | |
fft.forward(song.mix); | |
for (int i = 0; i < 0 + fft.specSize(); i++) | |
{ | |
line(i, height, i, height - fft.getBand(i) * 4); | |
} | |
fill(0); | |
rect(0, height - 2, width, 2); | |
} | |
//Waveform | |
void waveform() | |
{ | |
for (int i = 0; i < song.bufferSize() - 1; i++) | |
{ | |
line(i, 275 + song.left.get(i) * 50, i + 1, 275 + song.left.get(i+1)*50); | |
line(i, 325 + song.right.get(i) * 50, i + 1, 325 + song.right.get(i+1)*50); | |
} | |
fill(0); | |
} | |
//Line Visualizer | |
void lineVisualizer() | |
{ | |
for (int i = 0; i < song.bufferSize() - 1; i++) | |
{ | |
stroke(song.right.get(i) * 100, song.left.get(i) * 100, (song.left.get(i) * 100) + (song.right.get(i) * 100)); | |
line(i, 0, i, 600); | |
} | |
fill(255); | |
} | |
//Circle Visualizer | |
void circleVisualizer() | |
{ | |
for (int i = 0; i < song.bufferSize() - 1; i++) | |
{ | |
noStroke(); | |
fill(song.right.get(i)*100, song.left.get(i)*100, song.left.get(i)*100 + song.right.get(i) * 100); | |
//check to see if i is an integer (to cut down # of circles) | |
int roundedi = round(i); | |
if (i == roundedi) | |
{ | |
if (song.right.get(i) * 50 + song.left.get(i) * 50 > 25) | |
{ | |
ellipse(i, random(600), song.right.get(i) * 50 + song.left.get(i) * 50, song.right.get(i) * 50 + song.left.get(i) * 50); | |
} | |
} | |
} | |
stroke(0); | |
} | |
//Circle Strands | |
void dancingOctopus() | |
{ | |
frameRate(15); | |
fill(255); | |
for (int i = 0; i < song.bufferSize() - 1; i++) | |
{ | |
ellipse(song.left.get(i) * 1000, song.right.get(i) * 1000, i / 25, i / 25); | |
} | |
fill(0); | |
} | |
//Closes the song | |
void stop() | |
{ | |
song.close(); | |
minim.stop(); | |
super.stop(); | |
} | |
//Reset Events | |
void resetEvents() | |
{ | |
keyLeft = false; | |
keyRight = false; | |
} | |
//checks if keys were released | |
void keyReleased() | |
{ | |
if (key == CODED) | |
{ | |
//used for events | |
if (keyCode == LEFT) | |
{ | |
keyLeft = true; | |
instructions = false; | |
} | |
else if (keyCode == RIGHT) | |
{ | |
keyRight = true; | |
instructions = false; | |
} | |
} | |
//pause/play the song | |
if (key == ' ') | |
{ | |
if (paused) | |
{ | |
song.play(); | |
paused = false; | |
} | |
else | |
{ | |
song.pause(); | |
paused = true; | |
} | |
} | |
//show the description | |
if (key == 'd' || key == 'D') | |
{ | |
if (description) | |
{ | |
description = false; | |
} | |
else | |
{ | |
description = true; | |
} | |
} | |
//show the instructions | |
if (key == 'i' || key == 'I') | |
{ | |
if (instructions) | |
{ | |
instructions = false; | |
} | |
else | |
{ | |
instructions = true; | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment