Last active
August 29, 2015 14:18
-
-
Save davidfoerster/b341ff890150569c1594 to your computer and use it in GitHub Desktop.
Iggy Wave
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
//3D Spectrogram with Microphone Input | |
//Modified by kylejanzen 2011 - https://kylejanzen.wordpress.com | |
//Based on script wwritten by John Locke 2011 - http://gracefulspoon.com | |
//Output .DXF file at any time by pressing "r" on the keyboard | |
import processing.dxf.*; | |
import ddf.minim.analysis.*; | |
import ddf.minim.*; | |
FFT fftLin; | |
FFT fftLog; | |
Waveform audio3D; | |
Minim minim; | |
AudioInput microphone; | |
boolean record; | |
PFont font; | |
float camzoom; | |
float maxX = 0;float maxY = 0;float maxZ = 0; | |
float minX = 0;float minY = 0;float minZ = 0; | |
void setup() | |
{ | |
size(1250,750,P3D); | |
noStroke(); | |
// Initialise audio source (microphone) | |
minim = new Minim(this); | |
microphone = minim.getLineIn(Minim.STEREO, 4096); | |
background(255); | |
// Initialise Fast-Fourier-Transformer | |
fftLog = new FFT(microphone.bufferSize(),microphone.sampleRate()); | |
fftLog.logAverages(1,2); //adjust numbers to adjust spacing; | |
// Initialise wave form calculator and drawer | |
float w = float (width/fftLog.avgSize()); | |
float x = w; | |
float y = 0; | |
float z = 50; | |
float radius = 10; | |
audio3D = new Waveform(x,y,z,radius); | |
} | |
void draw() | |
{ | |
background(0); | |
directionalLight(126,126,126,sin(radians(frameCount)),cos(radians(frameCount)),1); | |
ambientLight(102,102,102); | |
if (frameCount>200) | |
{ | |
// adjust camera position depending on the amplitude of the highest(?) frequency band | |
for(int i = 0; i < fftLog.avgSize(); i++) | |
{ | |
float zoom = 1; | |
float jitter = (fftLog.getAvg(i)*2); | |
//println(jitter); | |
PVector foc = new PVector(audio3D.x+jitter, audio3D.y+jitter, 0); | |
PVector cam = new PVector(zoom, zoom, -zoom); | |
camera(foc.x+cam.x+50,foc.y+cam.y+50,foc.z+cam.z,foc.x,foc.y,foc.z,0,0,1); | |
} | |
} | |
// grab new data window from audio source and calculate FFT | |
fftLog.forward(microphone.mix); | |
// update and plot the wave form model | |
audio3D.update(); | |
// draw text annotations | |
audio3D.textdraw(); | |
if(record) | |
{ | |
beginRaw(DXF, "output.dxf"); | |
} | |
// draw wave forms outlines | |
audio3D.plotTrace(); | |
if(record) | |
{ | |
endRaw(); | |
record = false; | |
println("It's Done Bitches! Find your DXF!"); | |
} | |
} | |
void stop() | |
{ | |
// always close Minim audio classes when you finish with them | |
microphone.close(); | |
// always stop Minim before exiting | |
minim.stop(); | |
super.stop(); | |
} | |
/** | |
* Stores and draws wave form diagram | |
*/ | |
class Waveform | |
{ | |
float x,y,z; | |
float radius; | |
/** | |
* A queue to hold point data of past and current wave form windows | |
*/ | |
PVector[] pts = new PVector[fftLog.avgSize()]; | |
/** | |
* A queue to hold outline data of past and current wave form windows | |
*/ | |
PVector[] trace = new PVector[0]; | |
Waveform(float incomingX, float incomingY, float incomingZ, float incomingRadius) | |
{ | |
x = incomingX; | |
y = incomingY; | |
z = incomingZ; | |
radius = incomingRadius; | |
} | |
void update() | |
{ | |
plot(); | |
} | |
/** | |
* Plot wave form and store current data window in a size-limited queue. | |
*/ | |
void plot() | |
{ | |
for(int i = 0; i < fftLog.avgSize(); i++) | |
{ | |
int w = int(width/fftLog.avgSize()); | |
x = i*w; | |
y = frameCount*5; | |
z = height/4-fftLog.getAvg(i)*4; | |
stroke(0); | |
point(x, y, z); | |
pts[i] = new PVector(x, y, z); | |
trace = (PVector[]) expand(trace, trace.length+1); | |
trace[trace.length-1] = new PVector(pts[i].x, pts[i].y, pts[i].z); | |
} | |
} | |
/** | |
* Draw numerical diagram annoations | |
*/ | |
void textdraw() | |
{ | |
for(int i =0; i<fftLog.avgSize(); i++){ | |
pushMatrix(); | |
translate(pts[i].x, pts[i].y, pts[i].z); | |
rotateY(PI/2); | |
rotateZ(PI/2); | |
fill(255,200); | |
text(round(fftLog.getAvg(i)*100),0,0,0); | |
popMatrix(); | |
} | |
} | |
/** | |
* Draw wave form outline | |
*/ | |
void plotTrace() | |
{ | |
stroke(255,80); | |
int inc = fftLog.avgSize(); | |
for(int i=1; i<trace.length-inc; i++) | |
{ | |
if(i%inc != 0) | |
{ | |
beginShape(TRIANGLE_STRIP); | |
float value = (trace[i].z*100); | |
float m = map(value, -500, 20000, 0, 255); | |
fill(m*2, 125, -m*2, 140); | |
vertex(trace[i].x, trace[i].y, trace[i].z); | |
vertex(trace[i-1].x, trace[i-1].y, trace[i-1].z); | |
vertex(trace[i+inc].x, trace[i+inc].y, trace[i+inc].z); | |
vertex(trace[i-1+inc].x, trace[i-1+inc].y, trace[i-1+inc].z); | |
endShape(CLOSE); | |
} | |
} | |
} | |
} | |
void keyPressed() | |
{ | |
if (key == 'r') record = true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment