FFT lacking high frequency action

Hey there,
I’m new to Processing! I’m sending FFT analysis info to Grasshopper (a parametric tool for 3D software Rhino for anyone who isn’t familiar!) - I’m using my laptop microphone / system audio using a virtual audio cable. It kind of looks like it’s all working, except that I’m getting what looks like a lot of action in the low end and almost nothing at the high end - even if I feed it white noise. Any ideas? Am I just interpreting the numbers that I’m getting, incorrectly? I’m also aware that my code could be more elegant - please be gentle, this is my first day using Processing!

import hypermedia.net.*;
import processing.sound.*;
import java.util.Arrays;
import java.util.Collections;

FFT fft;
AudioIn in;
int bands = 128;
float[] spectrum = new float[bands];
float smoothingFactor = 0.99;
UDP udp;  // define the UDP object

void setup() {
  size(640, 360);
  background(255);

 udp = new UDP( this, 6001 );
  //udp.log( true ); 		// <-- printout the connection activity
  udp.listen( true );
  // Create an Input stream which is routed into the Amplitude analyzer
  fft = new FFT(this, bands);
   in = new AudioIn(this, 0);

  // start the Audio Input
  in.start();

  // patch the AudioIn
  fft.input(in);
}

void draw() { 
  background(125, 255, 125);

  fft.analyze(spectrum);
 
  float[] vals = spectrum;
  String[] sVals = new String[vals.length];
    
    StringBuffer sb = new StringBuffer();

  for (int i = 0; i < spectrum.length; i++) {
    spectrum[i] += (fft.spectrum[i] - spectrum[i]) * smoothingFactor;

    sVals[i] = "" + vals[i];
    // The result of the FFT is normalized
    // draw the line for frequency band i scaling it up by 5 to get more amplitude.
    line( i, height, i, height - spectrum[i]*height*5 ); 
  

    String joinedsVals = join(sVals, ","); 

              sb.append(sVals[i]);

}
    String str = Arrays.toString(sVals);
      
    String message  = (str);	// the message to send
    String ip       = "loopback";	// the remote IP address
    int port        = 6002;		// the destination port

    // formats the message for Pd
    message = message;
    // send the message
    udp.send( message, ip, port );
    println("Sending message: \""+message+"\"");
  }

Thanks in advance,
EK

1 Like

I think your graph looks about right to me, low end frequencies always have a much greater amplitude than higher frequencies.

On this song video I did it shows an EQ through the song but I had to limit the low end to make it presentable on the screen https://www.youtube.com/watch?v=DOZ7NmiJwAc

if you search for “fft graph” on google you will see lots of images very similar to yours. It can be useful to try and group frequencies into bands… low, medium, high rather than treating the spectrum as one group.

The bands I use in my app are these but its a case of playing around to suite your needs…

public float specLow = (float) 0.08; // 8%
public float specMid = (float) 0.20; // 20%
public float specHi = (float) 0.40; // 40%

Youll notice here Im not using the full 100% fft spectrum

1 Like

Cool, that all makes sense. I’ll try grouping the lows mids and highs and limiting as you suggest. Thank you! :slight_smile: :grinning: