我正在录制一个采样率为8000的fsk信号,它包含两个频率,'1'为800Hz,'0'为400Hz,编码消息为char'8'(00111000)eahc位用16384表示样本。我使用以下代码来捕获音频字节,唯一的区别是我将它们写入ByteArrayOutputStream。 https://stackoverflow.com/questions/23432398/audio-recorder-in-android-process-the-audio-bytes
完成录制后,每次向FFT函数发送16384个样本块,以分析播放的频率。出于某种原因,有时它可以工作(我设法提取正确的位),有时它不是0.0,在我的一个调试中,我看到它分析的第一个频率大约是1190Hz,当它应该大约400Hz时,另一个很奇怪事情发生的是当它应该是400赫兹时,第六位一直给我800hz。我检查了FFT结果向量(幅度),发现400Hz频率也存在且其幅度高于800Hz的幅度,所以我假设这是位'0'。 我做错了什么?
提取位的音频处理代码:
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--;
}
}
calculateFFt方法:
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;
}