# Color from FFT center frequency and its amplitude

Hello

This is my first post. I am trying to do a project with a variant of “sound painting” with a theremin. Let me explain a bit. The basic idea is to acquire sound from a theremin (with a microphone), then perform a FFT on the signal, calculate average frequency band and amplitude of the most dominant frequency. I want to do coloring with basic colors, so for that I would need to acquire a few frequencies from the theremin. For example I would generate 8 sound tones that have 8 specific frequencies with their amplitudes. To each of those colors I would assign a different color. In the end I would paint a rectangle with the paint that is “played” with the theremin.

To perform a FFT analysis I did no reinvent any thing. I took an example from Minim library, SoundSpectrum.

I changed the code to this:

``````import ddf.minim.analysis.*;
import ddf.minim.*;

Minim minim;
//AudioPlayer jingle;
AudioInput jingle;
FFT fftLin;
FFT fftLog;

float height3;
float height23;
float spectrumScale = 4;

PFont font;

void setup()
{
size(500, 500);
height3 = height/3;
height23 = 2*height/3;

minim = new Minim(this);
jingle = minim.getLineIn(Minim.MONO, 1024, 44100);

// loop the file
//jingle.loop();

// create an FFT object that has a time-domain buffer the same size as jingle's sample buffer
// note that this needs to be a power of two
// and that it means the size of the spectrum will be 1024.
fftLin = new FFT( jingle.bufferSize(), jingle.sampleRate() );

// calculate the averages by grouping frequency bands linearly. use 30 averages.
fftLin.linAverages( 100 );

// create an FFT object for calculating logarithmically spaced averages
fftLog = new FFT( jingle.bufferSize(), jingle.sampleRate() );

// calculate averages based on a miminum octave width of 22 Hz
// split each octave into three bands
// this should result in 30 averages
fftLog.logAverages( 22, 3 );

rectMode(CORNERS);

println(jingle.bufferSize());
println(jingle.sampleRate());
}

void draw()
{
background(0);

textFont(font);
textSize( 18 );

float centerFrequency = 0;
float centerFrequency1 = 0;
float amplitudeFrequency = 0;

// perform a forward FFT on the samples in jingle's mix buffer
// note that if jingle were a MONO file, this would be the same as using jingle.left or jingle.right
fftLin.forward( jingle.mix );
fftLog.forward( jingle.mix );

// draw the linear averages
{
// since linear averages group equal numbers of adjacent frequency bands
// we can simply precalculate how many pixel wide each average's
// rectangle should be.
int w = int( width/fftLin.avgSize() );
for(int i = 0; i < fftLin.avgSize(); i++)
{
centerFrequency = fftLin.getAverageCenterFrequency(i);
amplitudeFrequency = fftLin.getFreq(i);
// if the average center frequency is between a specified boundries and its amplitude is above specified level than write that frequency
if (centerFrequency >= 4000 && centerFrequency <= 4500 && amplitudeFrequency > 30)
{
//if (amplitudeFrequency > 30)
//  {
println(centerFrequency);
fill(255, 128);
text("Linear Average Center Frequency: " + centerFrequency, 5, height23 - 25);
//}
}
rect(i*w, height, i*w + w, height - fftLin.getAvg(i)*spectrumScale);
}
}

//float x1 = map(centerFrequency, 200, 800, 0, 255);
//float x2 = map(centerFrequency, 200, 800, 0, 150);
//float x3 = map(centerFrequency, 200, 800, 0, 125);
//fill(x1,x2,x3);
//rect(0, 0, 150, 150);
}
``````

So you can see, that I used the part where the linear average is calculated. I included getFreq() class to extract the amplitude from the average center frequency.

For testing I would just like to write to the console and to the screen when the criteria for the right frequency is met.
The main problem I have is the speed of the console output. It is laggy i.e. the response is not so quick in comparison to the original example where I change the input (so I am always acquiring the sound through the mic.

So what I would like to achieve is a smother (more fluent, more “real time” feeling) output of the center frequency.

Obviously the problem lies on my part in understanding and writing the code. I dont believe that the PC is to slow, my understanding is

So I am asking you kind, more experienced users to help a friend in need.

Best regards

`[ONE MONTH LATER…]`
For real-time data inspection I would recommend using `text()` and drawing the values each frame to the screen – and or writing to a log file.