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.