Reputation: 29
I need to perform spectral analysis of a simple wav file. The things I have already done :
Read file into byte array :
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = audioStream.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
fileByteArray = baos.toByteArray();
Then I transform it to the real values (doubles). I've got sample values stored in double[] array.
How can I make FFT of those samples + estimate fundamental frequency?
Using JTranforms library I tried something like this :
DoubleFFT_1D fft = new DoubleFFT_1D(reader.getSpectrum().getYvalues().length);
double[] x = reader.getSpectrum().getYvalues();
double[] frequencyArray = new double[x.lenght/2];
double[] amplitudeArray = new double[x.lenght/2];
fft.realForward(x);
int i=0;
for (int j = 0; j < x.length-2; j += 2) {
i++;
this.frequencyArray[i] = i;
this.amplitudeArray[i] = Math.sqrt(Math.pow(doub[j],2) + Math.pow(doub[j + 1],2));
}
Is it correct?
All suggestions are appreciated ;)
Upvotes: 1
Views: 1538
Reputation: 4821
You should use autocorrelation which can be computed efficiently with FFT:
DoubleFFT_1D fft = new DoubleFFT_1D(reader.getSpectrum().getYvalues().length);
DoubleFFT_1D ifft = new DoubleFFT_1D(reader.getSpectrum().getYvalues().length);
fft.realForward(x);
for (int i = 0; i < x.length/2; i++) {
x[2*i] = Math.sqrt(Math.pow(x[2*i],2) + Math.pow(x[2*i+1],2));
x[2*i+1] = 0;
}
ifft.realInverse(x);
for (int i = 1; i < x.length; i++)
x[i] /= x[0];
x[0] = 1.0;
This code gives you a list of values for which:
x[i]
: corelation with i shifts
So, for example if you have a high value (close to 1) for x[n]
, that means you have a fundemental signal period that is: n*(1000/sampleRateHz)
msecs. This is equivalent to a frequency of: sampleRateHz/(1000*n)
Upvotes: 2
Reputation: 70703
The values in the frequency array need to be related to the sample rate and the length of the FFT.
You will still need to solve the problem of determining the fundamental frequency versus the peak frequencies. For that, you may want to use a pitch detection/estimation algorithm, of which there are many (look for research papers on the topic).
Upvotes: 0