top of page

import ddf.minim.*;

import ddf.minim.analysis.*;

 

// Declare and construct three objects

Minim minim;

AudioPlayer test;

FFT fft;

 

// An array named "stars" filled with 2000 elements made with the Star() class

Star[] stars = new Star[2000];

 

// A global variable "speed" useful to control the speed of stars

float speed;

 

void setup() {

  size(1280, 720);

 

  // Draws all geometry with smooth (anti-aliased) edges at level two

  smooth(2);

 

  // Initialize the object

  minim = new Minim(this);

 

  // Specify that we want the audio buffers of the AudioPlayer

  // to be 1024 samples long because our FFT needs to have 

  // a power-of-two buffer size and this is a good size.

  test = minim.loadFile("final.mp3", 1024);

 

  // Create an FFT object that has a time-domain buffer 

  // the same size as test's sample buffer

  // Note that this needs to be a power of two 

  // and that it means the size of the spectrum will be half as large.

  fft = new FFT(test.bufferSize(), test.sampleRate());

 

  // Play the song

  test.play();

 

  // Fill the array with a for loop;

  // running 800 times, it creates a new star using the Star() class.

  for (int i = 0; i < stars.length; i++) {

    stars[i] = new Star();

  }

}

 

void draw() {

  // Clean the background in order to present new patterns

  background(0);

 

  // Perform a forward FFT on the samples in test's mix buffer,

  // which contains the mix of both the left and right channels of the file

  fft.forward(test.mix);

 

  // Re-maps the speed according to the amplitude of the requested frequency band 7

  speed = map(fft.getBand(7), 0, 100, 0, 300);

 

  // Set center of screen as initial point

  translate(width / 2, height / 2);

 

  // Draw each star, running the "update" method to update its position and

  // the "show" method to show it on the canvas.

  for (int i = 0; i < stars.length; i++) {

    stars[i].update();

    stars[i].show();

  }

}

class Star {

  // Create variables to specify the x and y of each star.

  float x;

  float y;

  

  // Create "z", a variable I'll use in a formula to modify the stars position.

  float z;

 

  // An other variable to store the previous value of the z variable.

  // (the value of the z variable at the previous frame).

  float pz;

 

  // Specify the alpha of patterns.

  float alpha;

 

  Star() {

    // Place values in the variables

    x = random(-width / 2, width / 2);  

    y = random(-height / 2, height / 2);

    

    // note: the z value can't exceed the width/2 (and height/2) value,

    // beacuse I'll use "z" as divisor of the "x" and "y",

    // whose values are also between "0" and "width/2".

    z = random(width / 2);

    

    // Set the previous position of "z" in the same position of "z",

    // which it's like to say that the stars are not moving during the first frame.

    pz = z;

  }

 

  void update() {

    // In the formula to set the new stars coordinates

    // I'll divide a value for the "z" value and the outcome will be

    // the new x-coordinate and y-coordinate of the star.

    // Which means if I decrease the value of "z" (which is a divisor),

    // the outcome will be bigger.

    // Wich means the more the speed value is bigger, the more the "z" decrease,

    // and the more the x and y coordinates increase.

    // Note: the "z" value is the first value I updated for the new frame.

    z = z - speed;

    

    // when the "z" value equals to 1, I'm sure the star have passed the

    // borders of the canvas( probably it's already far away from the borders),

    // so i can place it on more time in the canvas, with new x, y and z values.

    // Note: in this way I also avoid a potential division by 0.

    if (z < 1) {

      z = width / 2;

      x = random(-width /2, width / 2);

      y = random(-height /2, height / 2);

      pz = z;

    }

  }

 

  void show() {

    // Re-maps the alpha according to the amplitude of the requested frequency band 7    

    alpha = map(fft.getBand(7), 0, 100, 80, 255);

 

    fill(255, alpha);

    noStroke();

 

    // with theese "map", I get the new star positions

    // the division x / z get a number between 0 and a very high number,

    // we map this number (proportionally to a range of 0 - 1), inside a range of 0 - width/2.

    // In this way we are sure the new coordinates "sx" and "sy" move faster at each frame

    // and which they finish their travel outside of the canvas (they finish when "z" is less than a).

    float sx = map(x / z, 0, 1, 0, width / 2);

    float sy = map(y / z, 0, 1, 0, height / 2);    

 

    // I use the z value to increase the star size between a range from 0 to 16.

    float r = map(z, 0, width / 2, 5, 0);

    ellipse(sx, sy, r, r);

 

    // Here i use the "pz" valute to get the previous position of the stars,

    // so I can draw a line from the previous position to the new (current) one.

    float px = map(x / pz, 0, 1, 0, width / 2);

    float py = map(y / pz, 0, 1, 0, height / 2);

 

    // Placing here this line of code, I'm sure the "pz" value are updated after the

    // coordinates are already calculated; in this way the "pz" value is always equals

    // to the "z" value of the previous frame.

    pz = z;

 

    stroke(255, alpha);

    line(px, py, sx, sy);

  }

}

bottom of page