Fft doesn't work for 44100 sample rate
I asked a few questions here before analyzing the FSK signal. I am generating and recording an fsk signal with a sampling rate of 44100, it contains two frequencies: 934Hz for "1" and 510Hz for "0", the encoded message is a string that I convert to its binary edition, and each bit is represented with using 2048 samples. I have a 440Hz pre-tone before a tone representing the data itself. I used the following code to grab audio bytes, the only difference is that I write them to ByteArrayOutputStream https://stackoverflow.com/questions/23432398/audio-recorder-in-android-process-the-audio-bytes
I used to use 8000 sample rate and decided to improve the bit rate, so I changed the sample rate. When my recorder and transmitter was using 8000 sampling rate, I was able to find the starting point of the signal and analyze the data, for some reason, when I use 44100 sampling rate, my fft doesn't work well, I can't find the correct frequencies, I can't even see overtones that I once saw when running at 8000 sampling rate, I use the hann window function from this class and multiply each window: https://github.com/jpatanooga/Canova/blob/master/canova-data/canova -data-audio / src / main / java / org / canova / sound / musicg / dsp / WindowFunction.java .
Currently I am just pushing each 2048 sample in my recorded data to see the results. I'm not really sure why fft isn't working, no ideas?
I am using some of the functions that I am using:
A function to convert audio bytes to a doule array representing a normalized sine wave (data sent in small format):
private double[] convertBytes2SineWave(byte[] byteArray)
{
double[] doubleArray = new double[byteArray.length / 2];
short temp;
double normalizedVal;
for (int i=0; i<doubleArray.length; i++)
{
//The data send in little endian format - first byte is low order byte
byte bLow = byteArray[2*i];
byte bHigh = byteArray[2*i + 1];
temp = (short)(((bHigh & 0x00FF) << 8) | (bLow & 0x00FF));
normalizedVal = temp / 32767.0 ;
doubleArray[i] = normalizedVal;
}
return doubleArray;
}
Fft function:
public double[] calculateFFT(double[] signalChunk, int numFFTPoint)
{
double mMaxFFTSample;
double temp;
Complex[] y;
Complex[] complexSignal = new Complex[numFFTPoint];
double[] absSignal = new double[numFFTPoint/2];
for(int i = 0; i < numFFTPoint; i++)
{
temp = signalChunk[i];
complexSignal[i] = new Complex(temp,0.0);
}
y = FFT.fft(complexSignal);
mMaxFFTSample = 0.0;
mPeakPos = 0;
for(int i = 0; i < (numFFTPoint/2); i++)
{
absSignal[i] = Math.sqrt(Math.pow(y[i].re(), 2) + Math.pow(y[i].im(), 2));
if(absSignal[i] > mMaxFFTSample)
{
mMaxFFTSample = absSignal[i];
mPeakPos = i;
}
}
return absSignal;
}
Function for extracting data bits:
private void ExtractDataBits()
{
byte[] byteArrayData = ByteArrayAudioData.toByteArray();
sExtractedBits= new StringBuilder();
double binSize =((double)sampleRate/numberOfFFTPoints);
int HighFreqPos =(int) (freqOfHighTone/binSize);
int LowFreqPos =(int) (freqOfLowTone/binSize);
double[] daOriginalSine = convertBytes2SineWave(byteArrayData);
double[] smallArray;
int NumOfRuns = daOriginalSine.length /numberOfFFTPoints;
int startIndex = 0;
while(NumOfRuns > 0)
{
if(daOriginalSine.length - startIndex < numberOfFFTPoints)
break;
smallArray = new double[numberOfFFTPoints];
System.arraycopy(daOriginalSine, startIndex, smallArray, 0, numberOfFFTPoints);
smallArray = applyHannWindow(smallArray, numberOfFFTPoints);
double[]fftRes = calculateFFT(smallArray,numberOfFFTPoints);
if(fftRes[HighFreqPos] > fftRes[LowFreqPos])
sExtractedBits.append("1");
else
sExtractedBits.append("0");
startIndex = startIndex + numberOfFFTPoints;
NumOfRuns--;
}
}
source to share
No one has answered this question yet
Check out similar questions: