Skip to main content

How to get frequency from fft result?


I have recorded an array[1024] of data from my mic on my Android phone, passed it through a 1D forward DFT of the real data (setting a further 1024 bits to 0). I saved the array to a text file, and repeated this 8 times.



I got back 16384 results. I opened the text file in Excel and made a graph to see what it looked like(x=index of array, y=size of number returned). There are some massive spikes (both positive and negative) in magnitude around 110, 232, and small spikes continuing in that fashion until around 1817 and 1941 where the spikes get big again, then drop again.



My problem is that wherever I look for help on the topic it mentions gettng the real and imaginary numbers, I only have a 1D array, that I got back from the method I used from Piotr Wendykier's class:




DoubleFFT_1D.realForwardFull(audioDataArray); // from the library JTransforms.



My question is: What do I need to do to this data to return a frequency? The sound recorded was me playing an 'A' on the bottom string (5th fret) of my guitar (at roughly 440Hz) .


Source: Tips4allCCNA FINAL EXAM

Comments

  1. The complex data is interleaved, with real components at even indices and imaginary components at odd indices, i.e. the real components are at index 2*i, the imaginary components are at index 2*i+1.

    To get the magnitude of the spectrum at index i, you want:

    re = fft[2*i];
    im = fft[2*i+1];
    magnitude[i] = sqrt(re*re+im*im);


    Then you can plot magnitude[i] for i = 0 to N / 2 to get the power spectrum. Depending on the nature of your audio input you should see one or more peaks in the spectrum.

    To get the approximate frequency of any given peak you can convert the index of the peak as follows:

    freq = i * Fs / N;


    where:

    freq = frequency in Hz
    i = index of peak
    Fs = sample rate (e.g. 44100 Hz or whatever you are using)
    N = size of FFT (e.g. 1024 in your case)


    Note: if you have not previously applied a suitable window function to the time-domain input data then you will get a certain amount of spectral leakage and the power spectrum will look rather "smeared".



    To expand on this further, here is pseudo-code for a complete example where we take audio data and identify the frequency of the largest peak:

    N = 1024 // size of FFT and sample window
    Fs = 44100 // sample rate = 44.1 kHz
    data[N] // input PCM data buffer
    fft[N * 2] // FFT complex buffer (interleaved real/imag)
    magnitude[N / 2] // power spectrum

    capture audio in data[] buffer
    apply window function to data[]

    // copy real input data to complex FFT buffer
    for i = 0 to N - 1
    fft[2*i] = data[i]
    fft[2*i+1] = 0

    perform in-place complex-to-complex FFT on fft[] buffer

    // calculate power spectrum (magnitude) values from fft[]
    for i = 0 to N / 2 - 1
    re = fft[2*i]
    im = fft[2*i+1]
    magnitude[i] = sqrt(re*re+im*im)

    // find largest peak in power spectrum
    max_magnitude = -INF
    max_index = -1
    for i = 0 to N / 2 - 1
    if magnitude[i] > max_magnitude
    max_magnitude = magnitude[i]
    max_index = i

    // convert index of largest peak to frequency
    freq = max_index * Fs / N

    ReplyDelete

Post a Comment

Popular posts from this blog

[韓日関係] 首相含む大幅な内閣改造の可能性…早ければ来月10日ごろ=韓国

div not scrolling properly with slimScroll plugin

I am using the slimScroll plugin for jQuery by Piotr Rochala Which is a great plugin for nice scrollbars on most browsers but I am stuck because I am using it for a chat box and whenever the user appends new text to the boxit does scroll using the .scrollTop() method however the plugin's scrollbar doesnt scroll with it and when the user wants to look though the chat history it will start scrolling from near the top. I have made a quick demo of my situation http://jsfiddle.net/DY9CT/2/ Does anyone know how to solve this problem?

Why does this javascript based printing cause Safari to refresh the page?

The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex