/** * LiveSpectrum_grid * * Run an FFT on live line-in input, and plot the spectrum in dB. * Includes background grid. * '+' key moves the scale up (increases gain), '-' to move it down. * Based on http://processing.org/learning/libraries/forwardfft.html by ddf. * * 2010-01-22 Dan Ellis dpwe@ee.columbia.edu */ import ddf.minim.analysis.*; import ddf.minim.*; Minim minim; AudioInput in; FFT fft; float gain = 40; // in dB float dB_scale = 2.0; // pixels per dB int buffer_size = 1024; // also sets FFT size (frequency resolution) float sample_rate = 22050; float ytick_space = 2000; int spectrum_height = 200; // determines range of dB shown int legend_height = 20; int spectrum_width = 512; // determines how much of spectrum we see int legend_width = 40; void setup() { size(legend_width+spectrum_width, spectrum_height+legend_height, P2D); textMode(SCREEN); textFont(createFont("SanSerif", 12)); minim = new Minim(this); in = minim.getLineIn(Minim.MONO,buffer_size,sample_rate); // create an FFT object that has a time-domain buffer // the same size as line-in's sample buffer fft = new FFT(in.bufferSize(), in.sampleRate()); // Tapered window important for log-domain display fft.window(FFT.HAMMING); } void draw() { int x, y; // clear window background(0); // perform a forward FFT on the samples in input buffer fft.forward(in.mix); // add legend // frequency axis fill(255); stroke(128); y = spectrum_height; line(legend_width,y,legend_width+spectrum_width,y); // horizontal line // x,y address of text is immediately to the left of the middle of the letters textAlign(CENTER,TOP); for (float freq = 0.0; freq < in.sampleRate()/2; freq += ytick_space) { x = legend_width+fft.freqToIndex(freq); // which bin holds this frequency line(x,0,x,y+4); // axis + tick mark text(freq/1000 +"kHz", x, y+5); // add text label } // level axis x = legend_width; line(x,0,x,spectrum_height); // vertictal line textAlign(RIGHT,CENTER); for (float level = -100.0; level < 100.0; level += 20.0) { y = spectrum_height - (int)(dB_scale * (level+gain)); if (y < spectrum_height) { line(x-3,y,width,y); // axis + tick mark text((int)level+" dB",x-5,y); } } // draw current spectrum in white stroke(64,192,255); noFill(); for(int i = 0; i < spectrum_width; i++) { // draw the line for frequency band i using dB scale float val = dB_scale*(20*((float)Math.log10(fft.getBand(i))) + gain); if (fft.getBand(i) == 0) { val = -200; } // avoid log(0) y = spectrum_height - Math.round(val); if (y > spectrum_height) { y = spectrum_height; } line(legend_width+i, spectrum_height, legend_width+i, y); } } void keyReleased() { // +/- used to adjust gain on the fly if (key == '+' || key == '=') { gain = gain + 5.0; } else if (key == '-' || key == '_') { gain = gain - 5.0; } } void stop() { // always close Minim audio classes when you finish with them in.close(); minim.stop(); super.stop(); }