Processing

Obnoxious flies shown on the Prado’s MediaLab facade

Maybe you remember my previous post on Obnoxious flies a Processing sketch that I programmed for the MediaLab of the Prado museum, well it seems that they have used it !

In this video, at minute 37:56 you can see it running on the facade of the building.

 

[vimeo https://vimeo.com/67309091]

 

By the way, they have opened again the call for 2014.

Advertisements

Bass detection with Arduino

This post is a continuation of my previous post about sound analysis in Arduino.

In this post I will explain how I concretely managed to synchronize a light to the low frequencies of music (that is the bass).

As seen in my previous post, there are several alternatives for doing this job, so I will focus on a particular selection of tools:

The circuit:
The easy one: I use the Sparkfun’s electret kit.
The algorithm:
I will try to create a FIR filter for selecting only the low frequencies of the signal, and I will not tweak the analog-to-digital sampling frequency.

As the circuit is trivial, let’s see the details about the algorithm. For designing the filter I have used a wonderful free online tool, TFilter, from Iowegian.

The tool allows specifying the sampling frequency and the frequency response of the filter.
In my case I chose to allow passing frequencies for 0 to 200Hz and to block frequencies from 300Hz on. You can see the graph of the frequency response of my filter below:

Low pass digital filter frequency response

Low pass digital filter frequency response

As for the sampling frequency it’s tricky. It, in fact, depends on the code which then depends on the filter that you have. Generating the right filter is therefore an iterative process: you generate a first version of the filter with a certain sampling frequency (say 5000Hz), you import the code from the online tool (the code is automatically generated for you in the “source code” tab) and stick into your sketch, then you run a sketch that measures the actual sampling frequency, for instance by filtering a thousand samples and measuring the time needed for that. An example of such code is the following:

#include "LowPassFilter.c"

//The number of samples to buffer before analyzing them
int samplesN = 1000;
int micPin = 0;

LowPassFilter* filter;

void setup(){
  Serial.begin(9600);
  filter = new LowPassFilter();
  LowPassFilter_init(filter);
}

void loop(){
  long pow = 0;
  long filtpow = 0;
  int peak = 0;
  long start = millis();
  for(int k=0; k<samplesN; k++){
    int val = analogRead(micPin);
    LowPassFilter_put(filter, val);

    int filtered = LowPassFilter_get(filter);

    pow += ((long)val*(long)val)/samplesN;
    filtpow += ((long)filtered*(long)filtered)/samplesN;
    peak = max(peak, filtered);
  }
  long end = millis(); 
  float freq = ((float)samplesN * (float)1000) / ((float)end - (float)start);

  Serial.print(freq);
  Serial.print(" ");
  Serial.print(pow);
  Serial.print(" ");
  Serial.print(filtpow);
  Serial.print(" ");
  Serial.println(peak);
}

This code takes 1000 samples, filters them and computes the power of the signal, both the filtered and unfiltered ones and the sampling frequency. The power is simply the sum of the second power of the samples divided by the number of samples.
Note that I am using the integer implementation of the filter (in the source code tab of TFilter you can select floating points or integers in the “Number format” field) because integers arithmetic is much faster than floating points one.

Once you know what sampling frequency you go back to your TFilter tool and redesign the filter with the actual sampling frequency, but, given that the specifications are changed, it is very likely that the length of your filter will be different now, fact that will affect the computation required to run it and, therefore, the sampling frequency again!

So you need to do this work of: designing the filter + measuring actual sampling frequency + adjusting the filter, in some iterations (2 or 3 should be enough).

In my case the final sampling frequency is 2500Hz and the filter has 31 “taps” (the more complex is the filter the more taps you need, the more time you need to make it run at each sample).

So let’s check that it really filters the signal around 200-300Hz. I connected a pair of headphones to the microphone and measured the power of the signal while emitting some sine signals through them. The results is shown in the following table:

noise 50 Hz 100 Hz 200 Hz 300 Hz 500 Hz 800 Hz
total power 265760 307555 427998 458491 464047 466989 483063
filtered power 163604 198169 378124 275661 161191 162059 181106
peak 623 772 1087 950 548 537 613
filter/unfilter(db) -2.11 -1.91 -0.54 -2.21 -4.59 -4.60 -4.26

in terms of decibel it is not very impressive, but it does some filtering though. The problem here is that the circuit gets a lot of noise and a significant part of it goes into the low frequencies so, for instance, when you push a 800Hz sine the Arduino gets the 800Hz + the noise, therefore the total power is not so low.

Now let’s do something with this signal, for instance synchronizing a light on the bass of the music. For that we can use the measurement of the power or, even a simpler measurement, the peak.

To make it more responsive, instead of sampling 1000 samples, we can get 200 instead, and, in order to make it adaptive to the noise and general sound level we can play this trick: as the peak will move between a minimum and a maximum, we take the current peak and map the interval between the average and the maximum peak to a 0-1023 interval.

The final code appears something like this:

#include "LowPassFilter.c"

//The number of samples to buffer before analyzing them
int samplesN = 200;

int micPin = 0;

LowPassFilter* filter;

void setup(){
  Serial.begin(115200);
  filter = new LowPassFilter();
  LowPassFilter_init(filter);
}

int index = 0;
int maxpeak = 0 ;
int minPeak = 1023;

void loop(){
  int peak = 0;

  for(int k=0; k<samplesN; k++){
    int val = analogRead(micPin);
    LowPassFilter_put(filter, val);

    int filtered = LowPassFilter_get(filter);
    peak = max(peak, filtered);
  }  
  maxpeak = max(maxpeak, peak);
  minPeak = min(minPeak, peak);

  index++;
  if(index == 1000){
    maxpeak = 0;
    minPeak = 1023;
  }
  int lvl = map(peak, minPeak, maxpeak, 0, 1023);
  Serial.println(lvl);
}

It’s a pretty simple code as you see. Remember to also add the .h and .c files generated by the TFilter tool and also check that the sampling frequency hasn’t changed (which probably has). Please note also that there is a counter (index) that, each 1000 iterations, resets the minimum and maximum detected values. This helps if the sound level changes and you want your code to adapt to it.
From this code you can also make a sort of beat detector, for instance by setting a threshold and counting the number of times the peak goes on top of the threshold in a certain time window, but it would require more elaboration for sure.

In this code I am not activating any light, I am just sending the data to the computer to see how it is working. As the numbers run really fast on the serial monitor, I have created a simple Processing script that acts as a sort of equalizer bar, the code is here:

import processing.serial.*;

Serial myPort;

float MIN_VAL = 0;
float MAX_VAL = 1023;

void setup () {
  size(300, 500);        
  println(Serial.list());
  // Open whatever port is the one you're using.
  myPort = new Serial(this, Serial.list()[0], 115200);

  // don't generate a serialEvent() unless you get a newline character:
  myPort.bufferUntil('\n');
  background(0);
}

void draw () {
  // everything happens in the serialEvent()
}

void serialEvent (Serial myPort) {
  String inString = myPort.readStringUntil('\n');
  if (inString != null) {
    // trim off any whitespace:
    inString = trim(inString);
    // convert to a float and map to the screen height:
    float inval = float(inString); 

    inval = map(inval, MIN_VAL, MAX_VAL, 0, height-20);
     background(0);
    rect(10,10, width-20, inval);
  }
}

I have tested with some disco music and I have o say that the effect is quite good, when the bass is pumping you really see the bar going up and down at the same tempo, though, I have to say, you can also see some delay, which does not matter as long as you want to make some light controller anyway. By reducing the number of acquired samples to something less than 200 (for instance 100) you get a more responsive system but also a more sensible one, which makes the bar moving really fast and sometimes you see the noise clearly getting into the animation.

Obnoxious Flies, my Precessing sketch for the digital facade of the Medialab-Prado

The Media-Lab of the Prado museum of Madrid has an open call for showing processing sketches called programa la plaza (code the square).

Basically they have a 15 meters wide LED facade outside of the lab and they use it for interactive installations. The facade also has a video camera that is connected to their system and you can use the simple tracking algorithms they provide for your installation.

A selection of sketches will be shown during the After Arco event urban activities.

For the event I have just proposed my idea:

http://programalaplaza.medialab-prado.es/sketch/view/88de993485ebf12240521c29389c1ddf

It is an animation that shows some sort of flies moving around the screen randomly. When a user enters the area seen by the camera and starts to be tracked, flies will be attracted by him/her.

I hope it will be accepted !

Flying creatures, another Processing sketch

I have just finished reading chapter I  of this useful book: The Nature of code. At the end of the chapter there is a challenging exercise: creating a word with different creatures that move around with different patterns.

The sketch I have made this time is a sort of sky where there are two kinds of creatures: flies and birds.

Flies go around with sudden changes in their movement, birds are have more coherent flights but when they get close to flies they try to catch them.

The code is hosted on openprocessing: http://www.openprocessing.org/sketch/84168

Image

The Nature of code, my first sketch

I have discovered a wonderful handbook for learning some more advanced Processing: The Nature of Code. Although the book is specialized on cellular animation like graphics, it is full of useful tips for every kinds of Processing sketches.

Today I have studied the first chapter, about randomness and noises. Very, very useful. I have also done the  suggested exercises  quite simple, a part form the last one which is about a noise-driven 3D surface.

It took me almost one day to implement it, as I am not very comfortable with 3d programming, but in the end I made it.

Perlin Surface

Unfortunately it is not possible to embed Processing sketches into wordpress.com, but you can find the entire sketch here: http://www.openprocessing.org/sketch/84119

I will publish more while I keep studying the book. Promised!

MidiDraw

Hi,

I have just started a new project called MidiDraw.
Check the code here.
Here there’s the description (taken from the repository wiki):

The aim of this project is to provide a technical mean to translate drawings into musical messages. The idea is not the one of creating another Midi sequencer, but something like an “interpreter” of a free hand drawing.

Technically the program will draw mouse inputs and will generate “features” from the drawn points.

The generated midi messages are most likely to be controller messages (although in principle it is possible to generates notes as well).

There is also the possibility to use live images from an external video source, like webcams.

The project is still at its very first stage, but will grow quickly!