使用英特尔®MKL将实时域数据转换为复杂的频率和相位数据,以及逆数据

问题描述 投票:0回答:1

我正在编写一个音频插件,我想将代表采样值的一系列实数转换为代表频率和相位的复杂数组。然后,我希望能够做相反的事情,将频率和相位的复杂数组转换为一系列实数,从而重建原始数据。

我使用的是Intel MKL,我只看到执行实数->实数转换或复杂->复杂转换的可能性。这是我正在使用的参考:Intel MKL FFT Functions

在该参考文献中,有两个重载函数:DftiComputeForward和DftiComputeBackward。所以,我想用这些来做转换。在DftiCreateDescriptor的参考中,DFTI_FORWARD_DOMAIN可用的唯一选项是DFTI_COMPLEXDFTI_REAL,但没有用于混合转换的选项。

编辑我发现相位实际上等于atan(imaginary/real)。我不想误导任何人从问题中获取信息。

编辑我刚刚了解到最好使用atan2(imaginary,real)。评论中提供了更多信息。

c++ fft intel-mkl
1个回答
1
投票

每个实数都是复数:ℝ。因此,从时域中的floatdouble转到complex是微不足道的。语言为您做到了!

#include <complex>
#include <iostream>
int main() {
    double d = 42.0;
    std::complex<double> z = d;
    std::cout << d << " = " << z << '\n';
}

输出:42 = (42,0)

并且C ++标准库还执行其他所有操作。实际上,这很简单。图书馆一次只做了盒子上说的话。

甚至更好:std::complex提供数组访问。您可以通过引用或指针将std::complex<T>重新解释为T[2]。因此,std::complex可以“剥离”其身份,并传递到任何需要成对的浮点数或成对的双精度数的低级API中。

可以将复杂的频域数据转换为幅度和相位,然后转换回如下:

#include <complex>
#include <iostream>
int main() {
    std::complex<double> z{0.7071, 0.7071};
    double magnitude = abs(z);
    double phase = arg(z); // in radians

    std::cout << z << " ≈ (" << magnitude << "∠" << phase*180.0/M_PI << "°)\n";

    std::complex<double> z2 = std::polar(magnitude, phase);
    std::cout << " ≈ " << z2 << '\n';
}

输出:

(0.7071,0.7071) ≈ (0.99999∠45°)
 ≈ (0.7071,0.7071)

一旦获得“真实”数据,时域数据的虚部就不可能为零-这取决于您将对频域数据进行何种处理。您想使用abs函数将其转换回每个复杂时间样本的幅度。

C ++库中的某些东西过于复杂,以至于您必须打开该引用,否则您将不记得如何使用它。参见例如混乱称为随机数支持。啊。但是复数支持相对理智,甚至遵循复数算法教学中使用的符号:)

© www.soinside.com 2019 - 2024. All rights reserved.