I'm experimenting with the following Code:
//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.*;
import peasy.*;
PeasyCam cam;
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); //screen proportions
noStroke();
minim = new Minim(this);
microphone = minim.getLineIn(Minim.STEREO, 4096); //repeat the song
cam = new PeasyCam(this, 0, 0, 0, 50);
cam.setMinimumDistance(50);
cam.setMaximumDistance(500);
background(255);
fftLog = new FFT(microphone.bufferSize(),microphone.sampleRate());
fftLog.logAverages(1,2); //adjust numbers to adjust spacing;
float w = float (width/fftLog.avgSize());
print(fftLog.avgSize());
float x = w;
float y = 0;
float z = 10;
float radius = 100;
audio3D = new Waveform(x,y,z,radius);
}
void draw()
{
background(0);
// ambientLight(102,102,102);
if (frameCount>0)
{
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+100,foc.x+30,foc.y+30,foc.z+100,0,0,1);
}
}
//play the song
fftLog.forward(microphone.mix);
audio3D.update();
// audio3D.textdraw();
if(record)
{
beginRaw(DXF, "output.dxf");
}
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();
}
class Waveform
{
float x,y,z;
float radius;
PVector[] pts = new PVector[fftLog.avgSize()];
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();
}
void plot()
{
for(int i = 1; i < fftLog.avgSize(); i++)
{
int w = int(width/fftLog.avgSize());
x = i*w;
y = frameCount*5; // CHANGE THE SPEED
z = height/4-fftLog.getAvg(i)*4; //change multiplier to reduces height default '10'
stroke(0);
point(x, y, z);
pts[i] = new PVector(x, y, z);
//increase size of array trace by length+1
trace = (PVector[]) expand(trace, trace.length+1);
//always get the next to last
trace[trace.length-1] = new PVector(pts[i].x, pts[i].y, pts[i].z);
}
}
/* 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,255);
text(round(fftLog.getAvg(i)*100),0,0,0);
popMatrix();
}
} */
void plotTrace()
{
stroke(255,100);
int inc = fftLog.avgSize();
for(int i=1; i<trace.length-inc; i++)
{
if(i%inc != 0)
{
beginShape(POINTS);
strokeWeight(2);
fill(0, 0, 0, 100);
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;
}
What I currently try to achieve is to reduce the count of generated points on the (moving) (y-)axis. Currently it seems that every frame, a point is generated. My question therefore is fairly simple: How can I let it draw only e.g. every 5 frames? I just can't find the value, which manages that.
Thank you a lot.
You've got three options:
Option 1: Call the
frameRate()
function to reduce the number of frames that get drawn per second.Option 2: Use the
frameCount
variable and themodulus % operator
to determine whenX
frames have elapsed.Option 3: You could create your own variable that stores the number of frames that have elapsed.
Note that for the simple case, this is just doing what the modulus operator in option 2 is doing. In that case, modulus is probably better. But this becomes useful if you want, for example, different things to happen at different times. In that case you'd have multiple variables keeping track of the "lifetime" of whatever you want to track.
But for your example, option 2 is probably the best option.