在android中使用fft分析fsk信号

时间:2015-03-24 10:09:10

标签: android audio signal-processing fft

我正在录制一个采样率为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;
}

0 个答案:

没有答案