c++ - FFTW信号频谱

标签 c++ signals fft fftw spectrum

我目前正致力于实现信号频谱图。 我的输入数据:1.051、1.365、1.837、2.334、2.486、2.688、2.878、2.579、2.11、1.605、0.936、0.73、1.036、1.336、1.796、2.043、2.462、 2.935, 2.892, 2.609, 2.151, 1.641, 0.961, 0.738、0.767、1.303、1.503、2.004、2.435、2.931、2.908、2.641、1.935、1.423、0.988、0.747、0.755、1.018、1.465、1.966、2。 662, 2.919, 2.918, 2.669, 1.976, 1.462, 1.017, 0.757, 0.746、0.989、1.426、1.927、2.637、2.908、2.927、2.441、2.015、1.501、1.302、1.025、0.739、0.962、1.644、2.144、2.605、2。 895, 2.935, 2.467, 2.304, 1.797, 1.331, 1.039, 0.732, 0.936, 1.608, 2.103, 2.575, 2.88, 2.688, 2.493, 2.343, 1.835, 1.365, 1.054, 0.725, 0.913, 1.568, 2.067, 2.288, 2.867, 2.6 9, 2.516, 2.379, 1.877, 1.397, 1.072, 0.721, 1.144, 1.277, 1.77

你可以在我的截图上看到这些数据。是 basemap 。它仅包含 100 个点。并且不可能增加它的数量。

输入信号频率为 1000 Hz。它是可以改变的。

我使用 FFTW 获取频谱。

输入信号频率为 1000 Hz。在顶部图表中,它仅显示大约 200 Hz。这是主要问题。我想可能是我的代码有误,或者点数不够。

我的数据分析代码:

    QVectorDouble points(100);
    points = this->reader->ReadCOM(100);
    double timePassed = this->reader->timePassed;
    unsigned int n = points.count();
    double timeShift = timePassed / n;

    QVectorDouble signalX(n), signalY(n);

    for (unsigned int i = 0; i < n; i++)
    {
        signalX[i] = i*timeShift; // x goes from 0 to  timePassed to take points amount
        signalY[i] = points[i];
    }

    fftw::maxthreads = get_max_threads();
    unsigned int np = n / 2 + 1;
    size_t align = sizeof(Complex);

    array1<Complex> F(np, align);
    array1<double> f(n, align);

    rcfft1d Forward(n, f, F);

    for(unsigned int i = 0; i < n; i++) {
        f[i] = points[i];
    }

    Forward.fft(f, F);

    QVectorDouble spectrX(np), spectrY(np);
    for (int i = 0; i < np; i++)
    {
      spectrX[i] = i * 20; //multiply by 20 because np is (100/2 + 1) and chart maximum xOrigin is 1000
      spectrY[i] = abs(F[i]) / np;
    }

enter image description here

最佳答案

以下是一些不太正确的地方:

  • 在时域图中,1000Hz 采样率下的 100 个点应为您提供 0.1 秒的总持续时间。假定 timePassed 为 0.1 秒,用于 signalX 的公式是正确的。您应该研究为什么该变量实际上约为 0.4 秒。
  • 由于您在 0.1 秒内完成了 8 个完整周期,因此您应该获得 8*1/0.1 = 80Hz 的峰值频率。因此,显然频谱图的 x 轴缩放有问题。更具体地说,频率增量应设置为 1000/np 或 10Hz with np == 10。这将生成一个高达 500Hz 的曲线图,这是采样率的一半(与奈奎斯特定理一致),其中峰值将出现在正确的 80Hz 频率处。

关于c++ - FFTW信号频谱,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43209070/

相关文章:

c# - 离散傅里叶变换

c++ - std::cin 真的很慢

c++ - 转换 size_t 以允许 std::vector 中有更多元素

c - 辅助线程中的信号处理

c - 在 C 中重新启动程序

python - numpy.fft numpy.fft2 和 FFTW 用于二维数组

c++ - 在 C++ 中创建一个简单的数据包路由器,如何跟踪 'clients'?

c++ - 如何在 C++ 中正确表示非完整字节数字数组?

c - 在 C 中安全丢弃可变长度的标准输入字符的正确方法是什么?

java - 将变量从 Activity 传递到自定义 View 类