0

so I was able to solv my last problem but i stubmled upon the next already.

So I want to make a simple spectrogram but in oder to do so I want to understand how FFT-libaries work and what they actually calculate and return. (FFT and Signal Processing is the number 1 topic I will get into as soon as I have time but right now, I only have time for some programming exercises in the evening. ;) )

Here I just summarized the most important parts:

int framesPerSecond;
int samplesPerSecond;
int samplesPerCycle; // right now i want to refresh the spectogram every 

DoubleFFT_1D fft; 
WAVReader audioIn;

double audioL[], audioR[];
double fftL[], fftR[];

.....

framesPerSecond = 30;
audioIn= new WAVReader("Strobe.wav");
int samplesPerSecond = (int)audioIn.GetSampleRate();
samplesPerCycle = (int)(audioIn.GetSampleRate()/framesPerSecond);
audioL = new double[samplesPerCycle*2];
audioR = new double[samplesPerCycle*2];
fftL = new double[samplesPerCycle];
fftR = new double[samplesPerCycle];
for(int i = 0; i < samplesPerCycle; i++) { 
// don't even know why,... 
    fftL[i] = 0;
    fftR[i] = 0;
}
fft = new DoubleFFT_1D(samplesPerCycle);

.....

for(int i = 0; i < samplesPerCycle; i++) {
    audioIn.GetStereoSamples(temp);
    audioL[i]=temp[0];
    audioR[i]=temp[1];                        
}
fft.realForwardFull(audioL);  //still stereo
fft.realForwardFull(audioR);
System.out.println("Check");
for(int i = 0; i < samplesPerCycle; i++) { 
//storing the magnitude in the fftL/R arrays
    fftL[i] = Math.sqrt(audioL[2*i]*audioL[2*i] + audioL[2*i+1]*audioL[2*i+1]); 
    fftR[i] = Math.sqrt(audioR[2*i]*audioR[2*i] + audioR[2*i+1]*audioR[2*i+1]);
}

So the question is, if I want to know, what frequencys are in the sampled signal, how do I calculate them? (When I want to print the fftL / fftR arrays, I get some exponential formes at both ends of the array.)

Thx :)

ruhig brauner
  • 943
  • 1
  • 13
  • 35
  • possible duplicate of [How can I get DFT/FFT output frequencies in Hertz?](http://stackoverflow.com/questions/17390677/how-can-i-get-dft-fft-output-frequencies-in-hertz/17391353#17391353), [How to get Frequency from FFT result](http://stackoverflow.com/questions/4364823/how-to-get-frequency-from-fft-result/4371627#4371627), *et al* ... – Paul R Jul 02 '13 at 04:43
  • I found on of those topics but it didn't helped enough. Am I in general right with writing my audio samples in the first few slots of the array and then getting the RE and the IM part at the locations 2i nd 2i+1? (I get something like shown here but i somehow doubt, this is what I want to have. http://cnx.org/content/m12554/latest/?collection=col10253/1.7) – ruhig brauner Jul 02 '13 at 06:13
  • Well you need a window function prior to the FFT, and you need to calculate the *magnitude* of the FFT output for the first N/2 bins, then find the peaks. Which part are you having difficulty with ? – Paul R Jul 02 '13 at 06:42
  • I dont want to find peaks, I want to calculate the magitude for each frequency (more or less for ech frequency-area, like between 400 and 800 hz, 800 and 1600hz,..... So I think I already calculated the magnitude, am I right? I have problems calculating the values for the individual frequency ranges. (Like it is shown in specograms) So I actually dont know what to do with my fftR and fftL array wich contains the magnitude. (I also don't know, what the index i of my fftL-Array means.) – ruhig brauner Jul 02 '13 at 07:56
  • OK, so just sum the bin magnitudes across the frequencies of interest then. – Paul R Jul 02 '13 at 07:58
  • And it is normal that I get these interesting shapes like those in the link? And when I want to get the value of some high frequency-ranges or just want to get a smoother result, I need to increase the size of the used array, right? Since for example the highest magintude at i=1470 is frecuency =1469 * 44100 / 2940, the highest frecuency calculated is around 2/44100hz, right? – ruhig brauner Jul 02 '13 at 08:26
  • As I mentioned previously, you really need a window function prior to the FFT to avoid the smearing that comes from spectral leakage. – Paul R Jul 02 '13 at 08:53
  • EDIT: So when I want to reduce the leage, I trhow the window function over my samples bevore analysing it. so for every sample, reduce the value for a specific ammount. What window funcion works best for this kind of application? (Does the outer samples have to be 0 or near 0 to avoid leakage?) – ruhig brauner Jul 02 '13 at 09:11
  • This is all covered in the answers I linked to and related answers on SO - see [Wikipedia article on window functions](https://en.wikipedia.org/wiki/Window_function) and use a simple window such as von Hann. – Paul R Jul 02 '13 at 09:34
  • Do you mean this topic: http://stackoverflow.com/questions/4364823/how-to-get-frequency-from-fft-result I dont see anything related to window functions there. :( All I need to know is if i have to add the window function before or after the fft. (Thx for your help, btw.) – ruhig brauner Jul 02 '13 at 09:43
  • There are quite a few answers on SO that cover this in detail, e.g. http://stackoverflow.com/questions/3555318/implement-hann-window - between SO and Wikipedia you should have everything you need - and yes, the window function is applied *prior to* the FFT, as I mentioned above. – Paul R Jul 02 '13 at 10:24
  • Ou sorry. I skiped "prior". (English is not my native language, skipped it the first time you wrote it,...) Thx, that should answer all my questions. :) – ruhig brauner Jul 02 '13 at 10:28
  • No problem - good luck with your project - post a new question if you get stuck further on. – Paul R Jul 02 '13 at 10:52
  • Maybe this will help your understanding: http://blog.bjornroche.com/2012/07/frequency-detection-using-fft-aka-pitch.html – Bjorn Roche Jul 02 '13 at 14:41

1 Answers1

0

So I added the Window function but nothing realy changes. (It is a bit better but like you cant see I think there is a problem somewhere. I just post the parts where I calculate the arrays and where i print them:

short temp[] = new short[2];
for(int i = 0; i < samplesPerCycle; i++) {
     audioIn.GetStereoSamples(temp);
     double multiplier = 0.5*(1 - Math.cos(2*Math.PI*i/(samplesPerCycle-1)));
     audioL[i]=multiplier*temp[0];
     audioR[i]=multiplier*temp[1];                        
}

fft.realForwardFull(audioL);
fft.realForwardFull(audioR);
for(int i = 0; i < samplesPerCycle; i++) {                        
    fftL[i] = Math.sqrt(audioL[2*i]*audioL[2*i] + audioL[2*i+1]*audioL[2*i+1]);
    fftR[i] = Math.sqrt(audioR[2*i]*audioR[2*i] + audioR[2*i+1]*audioR[2*i+1]);
    if(fftL[i] > maxValue) {
        maxValue = fftL[i]; 
    }
    if(fftR[i] > maxValue) {
        maxValue = fftR[i]; 
    }
}
repaint();

And here I paint them

double dx = (double)this.getWidth()/samplesPerCycle;
for(int i = 0; i < samplesPerCycle; i++) {                            
    g.drawLine((int)(i*dx), this.getHeight(), (int)(i*dx),this.getHeight()-(int)((this.getHeight()*fftL[i])/maxValue));
}

And these are the results I get: http://www.pic-upload.de/view-19926382/FFTResult.jpg.html

Did i missed something important here?

ruhig brauner
  • 943
  • 1
  • 13
  • 35