/** * This sketch demonstrates how to use an FFT to analyze * the audio being generated by an AudioPlayer. * <p> * FFT stands for Fast Fourier Transform, which is a * method of analyzing audio that allows you to visualize * the frequency content of a signal. You've seen * visualizations like this before in music players * and car stereos. */
void setup() { size(720, 720, P3D); minim = new Minim(this); MidiBus.list(); myBus = new MidiBus(this, 0, 3); // Create a new MidiBus with no input device and the default Java Sound Synthesizer as the output device. // specify that we want the audio buffers of the AudioPlayer // to be 1024 samples long because our FFT needs to have // a power-of-two buffer size and this is a good size. in = minim.getLineIn(Minim.STEREO, 2048);
// loop the file indefinitely //jingle.loop();
// create an FFT object that has a time-domain buffer // the same size as jingle's sample buffer // note that this needs to be a power of two // and that it means the size of the spectrum will be half as large. fft = new FFT( in.bufferSize(), in.sampleRate() ); delay(2000); }
// perform a forward FFT on the samples in jingle's mix buffer, // which contains the mix of both the left and right channels of the file fft.forward( in.mix ); //for(int i = 0; i < fft.specSize(); i++) //{ // draw the line for frequency band i, scaling it up a bit so we can see it //line( i, height, i, height - fft.getFreq(value1*2) ); // println("VALUE: " + fft.getFreq(value1*2)); //}
}
void noteOn(int channel, int pitch, int velocity) { // Receive a noteOn println(); println("Note On:"); println("--------"); println("Channel:"+channel); println("Pitch:"+pitch); println("Velocity:"+velocity); }
void noteOff(int channel, int pitch, int velocity) { // Receive a noteOff println(); println("Note Off:"); println("--------"); println("Channel:"+channel); println("Pitch:"+pitch); println("Velocity:"+velocity); }
void controllerChange(int channel, int number, int value) { // Receive a controllerChange println(); println("Controller Change:"); println("--------"); println("Channel:"+channel); println("Number:"+number); println("Value:"+value); value1 = value;
}
So, here is my simple audiovisualizer with selective frequency bands via Midi. The probelm I'm having is the value of fft.getFreq() changes way to fast as it changes the size of the rect. The value of fft.getFreq() is what changes the shape.
The problem I'm having is that the square grows bigger then smaller waaay to fast.
Is there some kind of damper or some clever coding that I can do to make it more smooth of a transitition?
Basically this program is supposed to take Midi data input (the value 0 - 127) and apply it the get a specific frequency range of audio drawn to the screen.
I've been able to manually type the value such as '5' and then '200' to notice that it is working. 5 picks up the lower end while 200 is higher frequency white noise type.
However, now when I've patched some code to let my midi input change the frequency band... it doesn't show the real-time change. The value within the for loop just stays at 90.
I'm sure it's some rule i'm not aware of to change a value within' a for loop. Here is the bit.
for(int i = 0; i < fft.specSize(); i++)
{
// draw the line for frequency band i, scaling it up a bit so we can see it
line( i, height, i, height - fft.getFreq(value) );
println("VALUE: " + value);
}
}
And here is the code:
/** * This sketch demonstrates how to use an FFT to analyze * the audio being generated by an AudioPlayer. * <p> * FFT stands for Fast Fourier Transform, which is a * method of analyzing audio that allows you to visualize * the frequency content of a signal. You've seen * visualizations like this before in music players * and car stereos. */
myBus = new MidiBus(this, 0, 3); // Create a new MidiBus with no input device and the default Java Sound Synthesizer as the output device.
// specify that we want the audio buffers of the AudioPlayer // to be 1024 samples long because our FFT needs to have // a power-of-two buffer size and this is a good size. in = minim.getLineIn(Minim.STEREO, 1024);
// loop the file indefinitely //jingle.loop();
// create an FFT object that has a time-domain buffer // the same size as jingle's sample buffer // note that this needs to be a power of two // and that it means the size of the spectrum will be half as large. fft = new FFT( in.bufferSize(), in.sampleRate() );
}
void draw() { background(0); stroke(255);
int channel = 0; int pitch = 64; int velocity = 127;
// perform a forward FFT on the samples in jingle's mix buffer, // which contains the mix of both the left and right channels of the file fft.forward( in.mix );
for(int i = 0; i < fft.specSize(); i++) { // draw the line for frequency band i, scaling it up a bit so we can see it line( i, height, i, height - fft.getFreq(value) ); println("VALUE: " + value); } }
void noteOn(int channel, int pitch, int velocity) { // Receive a noteOn println(); println("Note On:"); println("--------"); println("Channel:"+channel); println("Pitch:"+pitch); println("Velocity:"+velocity); }
void noteOff(int channel, int pitch, int velocity) { // Receive a noteOff println(); println("Note Off:"); println("--------"); println("Channel:"+channel); println("Pitch:"+pitch); println("Velocity:"+velocity); }
void controllerChange(int channel, int number, int value) { // Receive a controllerChange println(); println("Controller Change:"); println("--------"); println("Channel:"+channel); println("Number:"+number); println("Value:"+value); }
Hello,
I've managed to patch together a Minim example to listen to the audio playing on the PC. Now I need to figure out what values to watch to cause different events.
So I want let's say, the bass (low freq) to produce a circle... and that circle to grow whenever the bass hits. And then I want the hi-hats (hi freq) to make a square and the square to grow everytime that hi hat frequency is hit.
My problem is I don't know where/how the frequency values are being stored and how I would determine which is currently on beat.
So basically my code would work something like this:
// bass is on a beat
if (Frequency 21khz volume is > previous volume){
draw a circle += 5
//hi-hat is on a beat
if (Frequency 80khz volume is > previous volume){
draw rect(x,x, +5, +5);
So:
How do I determine which frequency is being hit on the beat?
How do I determine whether or not the volume on that frequency has increased (for a beat) or decreased since its last beat?
I've tried println on a few different variables just to try to understand what values need to be evaluated (like which holes the frequency band or decible level) but I'm not making much progress.
Any help is much appreciated.
Thanks
/** * This sketch demonstrates how to use an FFT to analyze * the audio being generated by an AudioPlayer. * <p> * FFT stands for Fast Fourier Transform, which is a * method of analyzing audio that allows you to visualize * the frequency content of a signal. You've seen * visualizations like this before in music players * and car stereos. */
import ddf.minim.analysis.*; import ddf.minim.*;
Minim minim; AudioInput in; FFT fft;
void setup() { size(512, 200, P3D);
minim = new Minim(this);
// specify that we want the audio buffers of the AudioPlayer // to be 1024 samples long because our FFT needs to have // a power-of-two buffer size and this is a good size. in = minim.getLineIn(Minim.STEREO, 1024);
// loop the file indefinitely //jingle.loop();
// create an FFT object that has a time-domain buffer // the same size as jingle's sample buffer // note that this needs to be a power of two // and that it means the size of the spectrum will be half as large. fft = new FFT( in.bufferSize(), in.sampleRate() );
}
void draw() { background(0); stroke(255);
// perform a forward FFT on the samples in jingle's mix buffer, // which contains the mix of both the left and right channels of the file fft.forward( in.mix );
for(int i = 0; i < fft.specSize(); i++) { // draw the line for frequency band i, scaling it up a bit so we can see it line( i, height, i, height - fft.getBand(i)*10 ); println("buffer size: " + fft.getBand(i)); } }
Along the way I've had to convert alot of commands from what I assume is a result of 2.0+. I've come across this one and I'm not sure how to replace/fix it..
"Could not register mouseEvent() for ProjectionMapGL$Mapper@50a649" -
Anybody know what I need to replace these two statements with?
//Sign up for events parent.registerMouseEvent(this); parent.registerKeyEvent(this);
Entire code:
import java.util.*;
public class Mapper { ArrayList<PVector> buffer; HashSet<Triangle> triangles; PApplet parent; SamplerTriangle st; int w, h; boolean generateTriangles = true;
Triangle editedTriangle; boolean pointDragging = false; PVector pointDragged; /** * Constructor * @param parent The parent applet * @param w the width of the sampling canvas * @param h the height of the sampling canvas */
public Mapper(PApplet parent, int w, int h) { //Init this.parent = parent; buffer = new ArrayList<PVector>(); triangles = new HashSet<Triangle>();
//Set constraints for sampling the image this.w = w; this.h = h; //Set up default sample triangle st = new SamplerTriangle( new PVector(0, h), new PVector(w/2, 0), new PVector(w, h) );
//Sign up for events parent.registerMouseEvent(this); parent.registerKeyEvent(this); }
public void render(PImage img) { parent.noStroke(); background(0); for (Triangle t : triangles) { t.render(img, st.points[0], st.points[1], st.points[2]); } }
private void mouseClicked(PApplet p, int x, int y) { PVector v = new PVector(x,y); //Triangle Generator Mode if (generateTriangles){ if (buffer.size() == 2) { triangles.add( new Triangle(buffer.get(0), buffer.get(1), v) ); buffer.clear(); } else { buffer.add(v); } } else { //Triangle Editor Mode /** * Find the last triangle added and change it. Set the rest off */ PVector pv = new PVector(x,y); for (Triangle t : triangles){ if (contains(pv, t.points)){ t.setEditable(true); editedTriangle = t; } else { t.setEditable(false); } }
} }
public boolean save(String filename){ //TODO Write //TODO return significant info return true; }
public boolean load(String filename){ //TODO Write //TODO return significant info return true; }
void mouseEvent(MouseEvent event) { // get the x and y pos of the event int x = event.getX(); int y = event.getY(); PVector v = new PVector(x,y); switch (event.getAction()) { case MouseEvent.PRESS: try{ if (editedTriangle.editable){ for (PVector p : editedTriangle.points){ println(p.dist(v)); if (p.dist(v)< 10){ pointDragging = true; pointDragged = p; println("point caught!"); } } } } catch (NullPointerException e) { //do nothing } break; case MouseEvent.RELEASE: pointDragging = false; try { editedTriangle.setEditable(false); } catch (NullPointerException e) {
}
break; case MouseEvent.CLICK: mouseClicked(parent,x,y); break; case MouseEvent.DRAG: if (pointDragging){ pointDragged.set(v); } // do something... break; case MouseEvent.MOVE: // do something... break; } }
void keyEvent(KeyEvent event){ switch(event.getAction()){ case KeyEvent.PRESS: if (key == 'e') { generateTriangles=!generateTriangles; } else if (key == DELETE){ println("trying to delete"); try { if(editedTriangle.editable){ triangles.remove(editedTriangle); } } catch (NullPointerException e) {
} } break; default: break; } }
/** * Return true if the given point is contained inside the boundary. * See: http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html * @param test The point to check * @return true if the point is inside the boundary, false otherwise * */ private boolean contains(PVector test, PVector[] points) { int i; int j; boolean result = false; for (i = 0, j = 2; i < 3; j = i++) { if ((points[i].y > test.y) != (points[j].y > test.y) && (test.x < (points[j].x - points[i].x) * (test.y - points[i].y) / (points[j].y-points[i].y) + points[i].x)) { result = !result; } } return result; }
Okay. So I'm having a hard time figuring out this file structure of processing. What I did was drag the download folder 'processing-2.0' to my desktop and
I execute the processing application from there.
Along the way I discovered there is a 'processing' folder in 'Documents' with alot of the same file folders found in the folder on my desktop (modes, library, lib, etc. etc..).
Well... now I'm having problems with
'Cannot find a class or type named "Maxim"' in a project I downloaded from an online class.
Also - I get keep getting the
'projectQuads' needs to be in a folder called projectQuads. So I say yes, create the folder - and then now I get the syntax Error
The nested type "ProjectQuads" cannot hide an enclosing type.
What gives? Why am I having such a hard time? Can someone explain to me how to file folder structure works, or shoot me a link? I would greatly appreciate it :)
I've patched together some of the minim examples to achieve what I thought would be real-time audio reactive animation. I have the "kick, snare, hat" example (beatListener) open that I've modified with the AudioRecord example so that instead of kick,snare, and hat responding to a playing .mp3 file, they respond to the live record stream on my PC.
My attempt at the most obvious solution comes up to swap the 'song' variables with the 'line in' values produces the error "Line 23: The constructor AudioResponse.BeatListener(BeatDetect, AudioInput) is undefined" - which I've come to determine is because AudioInput is the wrong kind of value to be passed to BeatListener.
So my question is how would I go about achieving what I want? Can beatlistener not be used in a live recording stream way that I would like to? Will I need to do some type of value conversion?
Any and ALL feedback is always appreciated.
Thanks.
import ddf.minim.*;
import ddf.minim.analysis.*;
Minim minim;
BeatDetect beat;
BeatListener bl;
AudioInput in;
float kickSize, snareSize, hatSize;
void setup()
{
size(512, 200, P3D);
minim = new Minim(this);
in = minim.getLineIn(Minim.STEREO, 2048);
beat = new BeatDetect(in.bufferSize(), in.sampleRate());
beat.setSensitivity(300);
kickSize = snareSize = hatSize = 16;
bl = new BeatListener(beat, in);
textFont(createFont("Helvetica", 16));
textAlign(CENTER);
}
void draw()
{
background(0);
fill(255);
if ( beat.isKick() ) kickSize = 32;
if ( beat.isSnare() ) snareSize = 32;
if ( beat.isHat() ) hatSize = 32;
textSize(kickSize);
text("KICK", width/4, height/2);
textSize(snareSize);
text("SNARE", width/2, height/2);
textSize(hatSize);
text("HAT", 3*width/4, height/2);
kickSize = constrain(kickSize * 0.95, 16, 32);
snareSize = constrain(snareSize * 0.95, 16, 32);
hatSize = constrain(hatSize * 0.95, 16, 32);
}
void stop()
{
// always close Minim audio classes when you are finished with them
I'm trying to accomplish what I'm sure so many have done before, yet I'm not able to find anything of use when I've done my searches.
What I want is to be able to manipulate values based on the audio input played on my pc. When I poked around with the beatdetector, that seemed to be something I could make use of but I need to be able to have a real-time audio input. Is this possible? Is there anyway I can set it to listen to my onboard sound card, or a mic input and generate those values?