grape – LineWalk

I was mainly inspired by this old Youtube clip in which the person “plays” the Imperial March by writing a math equation. So for my line walk, I wanted something that didn’t necessarily “look” cool, but performed…cool. I wanted to see if the axidraw could sync up to the music. So I started looking through Processing’s Sound Library for anything on pitch detection. Instead I found amplitude and beat detectors which I turned into the following “records.”

waltz of the flowers

we will rock you

rickroll

_______ beat detection  ________

take on me

cantina band

bad guy

I think in order to get closer to my goal of an axidraw performance I’m going to look for libraries with pitch detection + maybe smoothing on the output. Otherwise I’ll add an additional threshold to the amplitude and simplify the movement of the record to make different notes more distinct.

code

import processing.sound.*;
import processing.svg.*;

// Declare the sound source and FFT analyzer variables
SoundFile sample;
Amplitude amp;

int num = 3500;
int range = 6;

float[] ax = new float[num];
float[] ay = new float[num]; 
// Define how many FFT bands to use (this needs to be a power of two)
int bands = 256;
float inc;
float growth;

float smoothingFactor = 0.3;

// Create a vector to store the smoothed spectrum data in
float[] sum = new float[bands];

// Variables for drawing the spectrum:
// Declare a scaling factor for adjusting the height of the rectangles
int scale = 5;
// Declare a drawing variable for calculating the width of the
float barWidth;
float rotater;

void setup() {
  size(768, 768);
  background(255);
  beginRecord(SVG, "badguy.svg");
  rotater = 0.0;
  inc = 0.0;
  growth = 0.05;

  for(int i = 0; i < num; i++) {
    ax[i] = 0;
    ay[i] = 0;
  }
  frameRate(30);
  
  // Calculate the width of the rects depending on how many bands we have
  barWidth = width/float(bands);

  // Load and play a soundfile and loop it.
  sample = new SoundFile(this, "badguy.aif");
  sample.loop();

  // Create the FFT analyzer and connect the playing soundfile to it.
  amp = new Amplitude(this);
  amp.input(sample);
}

void draw() {
  // Perform the analysis
  translate(width/2, height/2);
  for(int i = 1; i < num; i++) {
    ax[i-1] = ax[i];// *cos(rotater);
    ay[i-1] = ay[i];// *sin(rotater);
  }
  float r = map(amp.analyze(), 0, 0.1, inc, 40+inc);
  float x = r * cos(rotater);
  float y = r * sin(rotater);
  ax[num-1] = x;
  ay[num-1] = y;
  stroke(0);
  for(int i=1; i<num; i++) {    
    line(ax[i-1], ay[i-1], ax[i], ay[i]);
  }
  //stroke(255);
  //line(0,0,x,y);
  inc += growth;
  rotater+=0.01;
  if(int(rotater)==360)rotater = 0;
  if(int(inc) == 0) growth = 0.05;
  if(int(inc) == height/3) growth =-0.05;
}

void mousePressed() {
  endRecord();
  exit();
} 

the beat detection code is the same as above except you use a new BeatDetector (it also uses the analyze() function). Also my code is pretty terrible. In order to store all the measurements of beats/amplitudes I just used an array (after looking at some brownian motion stuff) which is not good for optimization.