android中fsk信号的fft分析
我正在记录采样率为8000的fsk信号,它包含两个频率,“1”为800Hz,“0”为400Hz,编码消息为char“8”00111000 eahc位,使用16384个样本表示。我使用以下代码捕获音频字节,唯一的区别是我将它们写入ByteArrayOutputStream 在我完成录制后,每次我都会向FFT函数发送16384个样本,以分析播放的频率。出于某种原因,有时它能工作我设法提取正确的位,有时它不能0.0,在我的一次调试中,我看到它分析的第一个频率大约是1190Hz,当它应该大约为400Hz时,另一件事发生了,第六个位一直给我800hz,当它应该为400Hz时。我检查了FFT结果向量幅值,发现400Hz频率也存在,其幅值高于800Hz,因此我假设这是位“0”。 我做错了什么 提取位的音频处理代码:android中fsk信号的fft分析,android,audio,signal-processing,fft,Android,Audio,Signal Processing,Fft,我正在记录采样率为8000的fsk信号,它包含两个频率,“1”为800Hz,“0”为400Hz,编码消息为char“8”00111000 eahc位,使用16384个样本表示。我使用以下代码捕获音频字节,唯一的区别是我将它们写入ByteArrayOutputStream 在我完成录制后,每次我都会向FFT函数发送16384个样本,以分析播放的频率。出于某种原因,有时它能工作我设法提取正确的位,有时它不能0.0,在我的一次调试中,我看到它分析的第一个频率大约是1190Hz,当它应该大约为400Hz
private void ExtractDataBits()
{
byte[] byteArrayData = ByteArrayAudioData.toByteArray();
sExtractedBits="";
double binSize =((double)sampleRate/numberOfFFTPoints);//fftpoints= 16384
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)
{
smallArray = new double[numberOfFFTPoints];
System.arraycopy(daOriginalSine, startIndex, smallArray, 0, numberOfFFTPoints);
double[] fftRes = calculateFFT(smallArray);
if(mPeakPos == HighFreqPos)
sExtractedBits += "1";
else if(mPeakPos ==LowFreqPos)
sExtractedBits += "0";
else
{
if(fftRes[HighFreqPos] > fftRes[HighFreqPos])
sExtractedBits+="1";
else
sExtractedBits+="0";
}
startIndex = startIndex + numberOfFFTPoints;
NumOfRuns--;
}
}
CalculateEfft方法:
public double[] calculateFFT(double[] signalChunk)
{
double mMaxFFTSample;
double temp;
Complex[] y;
Complex[] complexSignal = new Complex[numberOfFFTPoints];
double[] absSignal = new double[numberOfFFTPoints/2];
for(int i = 0; i < numberOfFFTPoints; 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 < (numberOfFFTPoints/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;
}
如前所述,使用基于FFT的方法进行此操作就像试图使用大锤敲碎核桃-您最终将陷入一片混乱。继续,当您准备好重新评估时,再看看更合适的方法。您希望iffftRes[HighFreqPos]>fftRes[HighFreqPos]行做什么?你是说iffftRes[HighFreqPos]>fftRes[LowFreqPos]吗?请注意,在这种情况下,使用ifmPeakPos>HighFreqPos+LowFreqPos/2可能会更好,但正如Paul提到的,还有其他更好的选择。您没有对信号加窗,fft可能是相邻位的重叠部分,一个目标是另一个目标的谐波,因此谐波失真可能导致错误结果,尤其是在没有良好窗口的情况下,您使用16k采样FFT来区分两个信号,这两个信号都只适合20个采样。看看Goertzel算法,如果你能调整频率,使一个不是另一个的整数倍。@SleuthEye谢谢你,我没有看到这个。为什么我要使用第二个条件?@Katie谢谢你的解释,我把频率改为934Hz和510Hz,我仍然得到一个比这两个更高的频率,它仍然被认为是谐波失真吗?