FFT analysis/music visualisation on Oscilloscope

edited August 8 in Share Your Work

Hi everybody. Here is some code that helps you show a very simple FFT analysis on an analog oscilloscope, a bit silly, but I like it :-)

Connect a cable to your sound input, and your sound output to an oscilloscope. It's far from perfect, and based heavily on other examples.

It uses the awesome new XYscope library, which is available here

import ddf.minim.analysis.*;
import ddf.minim.*;
import ddf.minim.signals.*;
import xyscope.*;
XYscope xy;

Minim minim;
AudioInput in;
FFT fft;

//utilities
float teller=0;

//values for Guitar

float[] myRGBuffer;//Right - Guitar
int bands = 512;// Define how many FFT bands we want
float[] sum = new float[bands];// Create a smoothing vector
float smooth_factor = 0.7; // Create a smoothing factor
float[] fftSmooth;
float guitarGain = 20; //to change gain input in software
int specSize;
int cols=32;//number of frequency bands to display
int rows=5;//'memory' depth
int scl = 100; //distance between z-points
float dampening=0.5;
float[][] terrain;


void setup()
{
  size(512, 512, P3D);
  background(0);
  minim = new Minim(this);
  in = minim.getLineIn(Minim.STEREO, 2048);
  fft = new FFT(in.bufferSize(), in.sampleRate());
  myRGBuffer = new float[in.bufferSize()];
  terrain = new float[cols][rows];
  xy = new XYscope(this, "");
  specSize = fft.specSize();
  fftSmooth = new float[specSize];
  //xy.smoothWaves(true);
}

void draw()
{

  xy.clearWaves();
  teller++;
  background(0);
  calcFFT();
  //draw code
  pushMatrix();
  translate (0, height, 0);
  rotateX(radians(175)); //amount of degrees rotation for 'camera'
  //rotateX(radians(teller)); //autorotate
  drawGuitarMatrix();
  popMatrix();
  xy.buildWaves();
  xy.drawAll();
}


void calcFFT() {
  fft.forward(in.mix);
  for (int z = rows; z >1; z--) { //looping backwards to avoid memory errors
    for (int x = cols-1; x >0; x--) {
      if (z==2) { //we never touch the first row, so it will always be on 'the ground'
        sum[x] += (fft.getBand(x) - (sum[x])) * smooth_factor;
        //sum[x] *=x;
        //if 
        terrain[x][z-1] = map(sum[x]*x, 0, 100, 0, guitarGain);//sum[x]*x = exponential scaling for higher frequencies
      } else {
        terrain[x][z-1] = terrain[x][(z-2)]*dampening;//fades out previous values by dampening the values
      }
    }
  }
}



void drawGuitarMatrix() {
  pushMatrix();
  xy.beginShape();
  for (int z = 0; z < rows-1; z++) {

    if (z%2>0) { //only even rows
      for (int x = cols-1; x >-1; x--) {
        float x1 = map(x, 0, cols, 0, width);
        xy.vertex((x1), terrain[x][z+1], ((z+1)*scl));
        xy.vertex((x1), terrain[x][z], (z*scl));
      }
      //xy.vertex(width, 0, ((z+1)*scl));
      //xy.vertex(0, 0, ((z+1)*scl));

    } else { //odd rows

      for (int x = 0; x <cols; x++) {
        float x1 = map(x, 0, cols, 0, width);
        xy.vertex((x1), terrain[x][z], (z*scl));
        xy.vertex((x1), terrain[x][z+1], ((z+1)*scl));
      }
     }
  }
 //last row&column
     if(!(rows%2>0)){xy.vertex(width, 0, (rows-1));}

       xy.vertex(0, 0, 0);

  xy.endShape();
  popMatrix();
}



void stop()
{
  // always close Minim audio classes when you finish with them
  in.close();
  minim.stop();

  super.stop();
}
Tagged:

Comments

Sign In or Register to comment.