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.