every now and again, it's nice to do something that you have no reason to be doing. of the many things that fall into this category for me, writing a script to take a president and three NBA all-stars on a spin around some classic highlights was maybe in the top 100. so i did just that. found a funky track (thank you Flamingosis), scrubbed the internet for some rare footage, headshots, and assorted graphics, and devised a little script to translate the song into syncopated and audio-triggered visual cacophony. the best dancer is the one having the most fun; let's boogie.
in the above project using a series of Fourier transforms to isolate high, low, and mid frequencies i mapped the bands to rotational velocities, displacement vectors, color overlays, etc. we get some funky visuals; which is fun, but not what the suits would call inherently useful... in a more practical sense, this kind of thing grew from my investigation into data visualizations and graphical representations for scientific communication. the same process could be used to show the migration pattern of water buffalo in sub-Saharan Africa or any number of more reasonable things.
full code pasted below for those who are into that kind of thing.
also, if you're really into this kind of thing, go check out processing by clicking here. it's free.

import processing.video.*;
import processing.sound.*;
SoundFile song;
Amplitude amp;
FFT fft;
AudioDevice device;
Movie film;
Bottle lt1, lt2, lt3, lt4; //bottle class
PImage ball, water, head1, head2, head3, head4; //images
int bands = 512; // number of bands to sample
float[] sum = new float[bands]; //fft array
float smooth_factor = 0.25; //smooth fft
float w_x, w_y, w_x1, w_y1, w_x2, w_y2, w_x3, w_y3; //water posistion
float t; //time step
float theta = 0; //rotation constant
float b_m; // ball mover
float h_m; //head mover
int x, y; //inital head pos
int hs = 80; //head size
int hp = 100; //head pos
int h_offset; //head movement
int hg; //head grower
int b_o = 75; //bottle offset
void setup() {
  size(720, 480); //canvas same size as film
  noStroke();
  imageMode(CORNER);
  device = new AudioDevice(this, 44000, bands); //fft sampled at 44000 over 512 buffer
  film = new Movie(this, "nba2.mp4"); //load the movie
  film.loop(); //play the movie in a loop
  ball = loadImage("ball.png"); //load images
  head1 = loadImage("shaq.png");
  head2 = loadImage("lj.png");
  head3 = loadImage("mj.png");
  head4 = loadImage("obama.png");
  water = loadImage("water.png");
  lt1 = new Bottle(b_o, b_o); //load in bottle objects to corners
  lt2 = new Bottle(width - b_o, b_o);
  lt3 = new Bottle(b_o, height - b_o);
  lt4 = new Bottle(width - b_o, height - b_o);
  amp = new Amplitude(this); //call amplitude
  song = new SoundFile(this, "track.mp3"); // call song
  song.play(); //play song
  fft = new FFT(this, bands); //set up fft
  fft.input(song); //run fft on song
  amp.input(song); //get amp from song
}
void draw() {
  image(film, 0, 0); //place film
  lt1.move(); //bottle class move/display
  lt1.display();
  lt2.move();
  lt2.display();
  lt3.move();
  lt3.display();
  lt4.move();
  lt4.display();

  /* use fourier transforms to identify frequencies
   fft.analyze();
   for (int i = 0; i < bands; i++) {
   // Smooth the FFT data by smoothing factor
   sum[i] += (fft.spectrum[i] - sum[i]) * smooth_factor;
   }
   */
  float size = map(amp.analyze(), 0, 1, 1, 10); //map the amp to larger values
  //ball.resize(int(100*size), int(100*size));//resize ball based on amp
  ball.resize(125, 125);
  if (size <= 2) { //if to move balls away from center
    b_m=-80;
    h_m = 1;
  } else {
    b_m = size*4;
    //h_m = size*0.5; // enable for head movement
  }
  
  pushMatrix(); // center co ords for symetry
  translate(width/2, height/2);
  imageMode(CENTER);
  float speed1 = map(amp.analyze(), 0, 1, 1, 5); //map the amp to larger values
  image(head1, w_x(t), w_y(t)); // heads in circular movement from rotation tab
  head1.resize(0, 120);
  image(head2, w_x1(t), w_y1(t));
  head2.resize(0, 100);
  image(head3, w_x2(t), w_y2(t));
  head3.resize(0, 120);
  image(head4, w_x3(t), w_y3(t));
  head4.resize(0, 100);
  if (speed1 <= 2.5) { //rotation speed of heads
    t+=speed1;
  } else if (speed1 > 2.5 && speed1 <=3.5) {
    t+=-speed1*10;
  }
  else if(speed1 > 3.5){
    t+=speed1*1.5;
  }

  theta+=speed1; //rotation based on amp
  rotate(radians(theta));
  x=80;
  y=80;

  image(ball, x + b_m, y + b_m); //four ball copies
  image(ball, -x - b_m, y + b_m);
  image(ball, x + b_m, -y - b_m);
  image(ball, -x -b_m, -y - b_m);
  popMatrix();
  imageMode(CORNER);
  pushMatrix();
  translate(0, 0); //reset matrix
  /* 
   if (speed1>2) { //moves heads on mid + amplitudes
   h_offset=33;
   hg=40;
   } else {
   h_offset=0;
   hg=0;
   }
   */
  /* 
   //head size dialater
   head1.resize(hs+hg, hs+hg); //make heads the same size and 
   image(head1, 0+h_offset, 0+h_offset);
   head2.resize(3*hs/4+hg, hs+hg);
   image(head2, width-hp-h_offset, 0+h_offset);
   head3.resize(hs+hg, hs+hg);
   image(head3, 0+h_offset, height-hp-h_offset);
   head4.resize(hs+hg, hs+hg);
   image(head4, width-hp-h_offset, height-hp-h_offset);
   */
  popMatrix();
}
void movieEvent(Movie m) { //update movie frames
  m.read();
}
back to top ↑