Forums

Convert FFT to equal temper scale or octave

Started by Unknown October 29, 2013
I want to represent the audio spectrum of a signal. (I don't need to reproduce the signal, just represent it).  The FFT gives linearly space bins, but I want to represent it as a log scale.  I've read posts about constant Q transforms and/or using filters to capture each octave.  The first is a bit above me (I've gone from paper to implementation before and its tough), and the second seems unnecessary for what I want.  Also, I'm new to C (from python) which is what I want to accomplish this in (for an Arduino) very resource limited.

I was thinking that to simply represent the bins of the FFT logarithmically, I could just group the bins.  

bin(1)' = bin(1)  #bin 1 prime is just bin 1
bin(2)' = bin(2)+bin(3)
bin(3)' = bin(4)+bin(5)+bin(6)+bin(7)
...
bin(n)' = bin((n-1)**2) + ... + bin(n**2-1)

Oh jeeze, at even only 128 samples, is this a terrible idea? And then, I'd really rather have the output spaced in 12ths of an octave (each bin represents a twelfth root of two times greater frequency, rather than 2 times).  If the above idea works, is there a way to pad and/or interpolate so that I can get the data as equal tempered? 

I'd be very happy with 6 to 8 octaves. 

So 

1)is this way reasonable for octaves?
2)is equal temper this way possible?
3)Is my head up my butt and I should use filters or something?
4)Can you point me to c or c++ code that does it?

Much thanks,
Elliot
offonoffoffonoff@gmail.com wrote:

> I want to represent the audio spectrum of a signal. (I don't need to > reproduce the signal, just represent it). The FFT gives linearly space > bins, but I want to represent it as a log scale. [..] > > I was thinking that to simply represent the bins of the FFT > logarithmically, I could just group the bins. > > bin(1)' = bin(1) #bin 1 prime is just bin 1 > bin(2)' = bin(2)+bin(3) > bin(3)' = bin(4)+bin(5)+bin(6)+bin(7) > ... > bin(n)' = bin((n-1)**2) + ... + bin(n**2-1) > > Oh jeeze, at even only 128 samples, is this a terrible idea?
With 128 samples the low frequency range will have a bad resolution.
> And then, I'd > really rather have the output spaced in 12ths of an octave (each bin > represents a twelfth root of two times greater frequency, rather than 2 > times). If the above idea works, is there a way to pad and/or interpolate > so that I can get the data as equal tempered?
Yes - you can weight the bins accordingly.
> 4)Can you point me to c or c++ code that does it?
Download my old Math library at http://huennebeck-online.de/software/download/src/index.html http://huennebeck-online.de/software/download/src/libAHmath-0.3.src.tar.gz (direct link) Class ReduceSpectrum should do what you need (member function processLogXScale). bye Andreas -- Andreas H�nnebeck | email: acmh@gmx.de ----- privat ---- | www : http://www.huennebeck-online.de Fax/Anrufbeantworter: 0721/151-284301 GPG-Key: http://www.huennebeck-online.de/public_keys/andreas.asc PGP-Key: http://www.huennebeck-online.de/public_keys/pgp_andreas.asc