修复我的 FFT 图

信息处理 fft 窗函数 爪哇
2022-02-14 08:15:07

我正在尝试绘制我的 FFT 文件。这是我的结果。我做了我的 FFT 应用程序:

我想获得与 WaveSpectra 情节非常相似的东西,请告诉我我的错误..

我的 FFT 我的 FFT

WaveSpectra 的结果 WaveSpectra 的 波谱版 其他结果 其他与 WaveSpectra

这是我的代码:

double[] Samples = null;
try {

  RandomAccessFile rafr = new RandomAccessFile(TheFile, "r");  //TheFile String with path and WAV filename
  //double[] getSamplesFile(rafr,"left",0,8192)  //returns the first 8192 samples of left channel
  Samples = getSamplesFile(rafr,Channel,iPosition,iSizeFFT);
  rafr.close();
}
catch (IOException e) { System.out.println(e.toString()); }

应用窗函数

现在我正在尝试将 Window 函数应用于 Samples,检查下面的代码

//double[] getWindow(8192,"hamming"); //was verified against matlab
Samples = applyFilter(Samples,getWindow(iSizeFFT,sWindow));

试图规范化

得到 FFT 数组每个复数项的绝对值的 Log10,然后乘以 20

//fft:  Returns a complex array with FFT (the result was tested and it is equal to Matlab)
//getArrayComplexMod: Returns a double array with absolute value of each complex number
//getRealArrayLog10: Returns a double array with Math.log of each double element
//getRealArrayScalarMult: Returns a double array multiplying each double element with 20.0

Samples = getRealArrayScalarMult(getRealArrayLog10(getArrayComplexMod(fft(Samples))),20.0);

获取以赫兹为单位的频率

//Now the freq or bins
double[] bins = new double[iSizeFFT];  //Size 8192
Integer SmplRt = 8000; 
for (int i = 0; i < iSizeFFT; i++) {
  bins[i] = (double)i*SmplRt/iSizeFFT;
}

将过滤器(或汉明窗)应用于样本的代码。

http://en.wikipedia.org/wiki/Finite_impulse_response#Definition

  static double[] applyFilter(double[] dSamples, double[] dFilter) {
    return applyFilter(dSamples, dFilter, 0);
  }

  static double[] applyFilter(double[] dSamples, double[] dFilter, int PosSample) {
    double[] filteredSamples = new double[dSamples.length - PosSample];
    for (int i = PosSample; i < dSamples.length; i++) {
      filteredSamples[i - PosSample] = 0;
      for (int j = 0; j < dFilter.length; j++) {
        if(!((i - j) < 0)) {
          filteredSamples[i - PosSample] += dSamples[i-j]*dFilter[j];
        }
      }
    }
    return filteredSamples;
  }

编辑1: 按照@hotpow2 的回答,解决了!

在此处输入图像描述

2个回答

您似乎正在将数据与您的窗口进行卷积,而不仅仅是将数据乘以您的窗口。例如

windowedSamples[i] = window[i] * data[i]

没有任何嵌套的卷积循环。

这通常是一个适合 Stack Overflow 的编程问题,但您缺少一部分。Wave Spectra 的频率刻度是对数的,在您的图中它是线性的。通常像semilogx正在工作的功能。然后它只是设置 x 轴刻度。