Issue displaying FFT in a circle (Minim)

edited October 2013 in Library Questions

Hi there, I'm trying to make some animations based on music and I learned about minim and FFT, so I'm giving it a shot. I loked out for the quick start guide on minim and there was a code about "Drawing a Frequency Spectrum", so I took that and changed a bit to make the buffer be drawn in a circle. The thing is it's not looking how I imagined and it's bugging a lot. This is the code:

import ddf.minim.*;
import ddf.minim.analysis.*;

Minim minim;
AudioPlayer song;
FFT fft;
float angle = 0;

void setup()
{
  size(512, 500);
  minim = new Minim(this);
  song = minim.loadFile("nocturne.mp3", 512);
  song.play();
  fft = new FFT(song.bufferSize(), song.sampleRate());
}

void draw()
{
  background(0);
  fft.forward(song.mix);
  stroke(255);

  /**
   * The loop displays the buffer values
   * in a circular fashion. The problem is that
   * are to many values being displayed so
   * it becomes a circle with varying stroke
   * size, instead of a circle with wavering stroke.
   */ 
  for(float j = 0; j <= 360; j++){
    angle = radians(j);
    for(int i = 0; i < song.left.size() - 1; i++){
      point(width/2 + 100*cos(angle)*(1 - song.left.get(i)), height/2 + 100*sin(angle)*(1 - song.left.get(i)));
    }
  }
}

void stop()
{
  song.close();
  minim.stop();
  super.stop();
}

The original code was basically the same but with this for loop:

  for(int i = 0; i < song.left.size() - 1; i++)
  {
    line(i, 50 + song.left.get(i)*50, i+1, 50 + song.left.get(i+1)*50);
    line(i, 150 + song.right.get(i)*50, i+1, 150 + song.right.get(i+1)*50);
  }

It can be found here: original code in Drawing a Frequency Spectrum section

I was expecting to create something more like this:

image alt text

I've alredy tryed changing the loops increment values with no luck. Any help would be appreciated.

Oh, and you need to change the sound to any sound for the code to work, in: song = minim.loadFile("nocturne.mp3", 512);

Tagged:

Answers

  • you've got a double nested loop there - you're drawing all the values for all the angles.

    note how the original code only has one loop.

  • Hi, thanks for the quick reply.

    I changed the code to make a single loop. But now I'm getting a weird second line of dots from 210º to 360º or 7PI/6 to 2PI. I'm not sure why that line is there.

            for(int i = 0; i < song.left.size() - 1; i++){
              angle = radians(i);
              point(width/2 + 150*cos(angle)*(1 - 2*song.left.get(i)), height/2 + 150*sin(angle)*(1 - 2*song.left.get(i)));
            }
    

    image alt text

  • Answer ✓

    that's because you have 512 samples and only 360 angles in your circle

    i will also predict that your next post will be how the end of the line doesn't match up with the start 8)

  • edited October 2013

    Indeed. Not exactly what I expected but I can see why that happens. Everytime the draw class updates the loop starts over in i = 0.

      for(int i = 0; i < song.left.size() - 1; i++){
        angle = radians(i*360/511);
        point(width/2 + 150*cos(angle)*(1 - 2*song.left.get(i)), height/2 + 150*sin(angle)*(1 - 2*song.left.get(i)));
      }
    

    I guess there is no solution to that.

    image alt text

  • mirror the data vertically - two circles, both complete.

    (duplicate line 3, change + 150 * sin to - 150 * sin)

Sign In or Register to comment.