superavi
superavi

Reputation: 15

Processing fft crash

Weird thing. I keep getting processing or java to crash with this code which is based on a sample code from the processing website.

On pc it doesn't work at all, on one mac it works for 5 seconds until it crushes and on another mac it just crust and gives me this:

libc++abi.dylib: terminating with uncaught exception of type std::runtime_error: RtApiCore::probeDeviceOpen: the device (2) does not support the requested channel count. Could not run the sketch (Target VM failed to initialize).

Do you think it's a problem with the library or with the code? If it's a problem with the library, could you recommend the best sound library to do something like this?

Thank you :)

import processing.sound.*;

FFT fft;
AudioIn in;
int bands = 512;
float[] spectrum = new float[bands];

void setup() {
  size(900, 600);

  background(255);

  // 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(255);
  int midPointW = width/2;
  int midPointH = height/2;
  float angle = 1;
  fft.analyze(spectrum);
  //float radius = 200;

  for(int i = 0; i < bands; i++){
    // create the actions for placing points on a circle
    float radius = spectrum[i]*height*10;
    //float radius = 10;
    float endX = midPointW+sin(angle) * radius*10;
    float endY = midPointH+cos(angle) * radius*10;
    float startX = midPointW+sin(angle) * radius*5;
    float startY =  midPointH+cos(angle) * radius*5;
  // The result of the FFT is normalized
  // draw the line for frequency band i scaling it up by 5 to get more amplitude.
    line( startX, startY, endX, endY);
    angle = angle + angle;
    println(endX, "" ,endY);
 // if(angle > 360){
 //     angle = 0;
 //   }
  }       
}

Upvotes: 0

Views: 355

Answers (1)

George Profenza
George Profenza

Reputation: 51837

If you print the values you use like angle and start x,y you'll notice that:

  1. start/end x,y values become NaN(not a number - invalid)
  2. angle quickly goes to Infinity (but not beyond)

One of the main issues is this line:

angle = angle + angle;

You're exponentially increasing this value which you probably don't want. Additionally, bare in mind trigonometric functions such as sin() and cos() use radians not degrees, so values tend to be small. You can constrain the values to 360 degrees or TWO_PI radians using the modulo operator(%) or the constrain() function:

angle = (angle + 0.01) % TWO_PI;

You were very close though as your angle > 360 check shows it. Not sure why you've left that commented out.

Here's your code with the tweak and comments

import processing.sound.*;

FFT fft;
AudioIn in;
int bands = 512;
float[] spectrum = new float[bands];

void setup() {
  size(900, 600);

  background(255);

  // 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(255);
  int midPointW = width/2;
  int midPointH = height/2;
  float angle = 1;
  fft.analyze(spectrum);
  //float radius = 200;

  for (int i = 0; i < bands; i++) {
    // create the actions for placing points on a circle
    float radius = spectrum[i] * height * 10;
    //float radius = 10;
    float endX = midPointW + (sin(angle) * radius * 10);
    float endY = midPointH + (cos(angle) * radius * 10);
    float startX = midPointW + (sin(angle) * radius * 5);
    float startY =  midPointH + (cos(angle) * radius * 5);
    // The result of the FFT is normalized
    // draw the line for frequency band i scaling it up by 5 to get more amplitude.
    line( startX, startY, endX, endY);
    //angle = angle + angle;
    angle = (angle + 0.01) % TWO_PI;//linearly increase the angle and constrain it to a 360 degrees (2 * PI)
  }
}

void exit() {
  in.stop();//try to cleanly stop the audio input
  super.exit();
}

The sketch ran for more than 5 minutes but when closing the sketch I still encountered JVM crashes on OSX. I haven't used this sound library much and haven't looked into it's internals, but it might be a bug.

If this still is causing problems, for pragmatic reasons I'd recommend installing a different Processing library for FFT sound analysis via Contribution Manager. Here are a couple of libraries:

  1. Minim - provides some nice linear and logarithmic averaging functions that can help in visualisations
  2. Beads - feature rich but more Java like syntax. There's also a free book on it: Sonifying Processing

Both libraries provide FFT examples.

Upvotes: 1

Related Questions