我有两个频率几乎相同的信号,我想找到它们之间的相移,因为我使用的是微控制器,所以我想以更便宜的方式来做。
我知道如何计算特定频率仓(每个信号)的 Goertzel,但是如何使用 Goertzel 计算这个仓的角度?
如果您知道较低的计算方法,请指教。
谢谢
我有两个频率几乎相同的信号,我想找到它们之间的相移,因为我使用的是微控制器,所以我想以更便宜的方式来做。
我知道如何计算特定频率仓(每个信号)的 Goertzel,但是如何使用 Goertzel 计算这个仓的角度?
如果您知道较低的计算方法,请指教。
谢谢
如果两个 Goertzel 滤波器的复频率 bin 输出为和,您可以将相位计算为和, 在哪里返回实部和返回参数的虚部。大多数编程语言都有两个参数功能。相位差可以计算为, 在哪里表示取复共轭,为你节省一个以一个复数乘法为代价,对相位进行评估和包装。
还有一个技巧可以计算. 乘以 Goertzel 输出通过第二个输入信号和低通滤波结果。在频域中它看起来像这样:

低通滤波隔离对应于. 这以低通滤波器为代价为您节省了一个 Goertzel 滤波器。如果你使用这个技巧,你还必须考虑低通滤波器引起的相移。
为了快速请参阅在 FPGA 上计算定点 atan2 的方法。
以下只是我自己的代码中的一个懒惰的复制粘贴,以防您被卡在 goertzel 过滤器的实/图像提取的实现中。否则,去看看奥利的答案。
template<typename Scalar, class Vector>
static std::complex<Scalar> goertzel(const Vector & data, std::size_t size, Scalar omega)
{
Scalar sine, cosine, coeff, q0(0), q1(0), q2(0);
sine = sin(omega);
cosine = cos(omega);
coeff = 2.0 * cosine;
for (Types::fint_t t = 0; t < size; t++)
{
q0 = coeff * q1 - q2 + data[t];
q2 = q1;
q1 = q0;
}
Scalar real = (q1 - q2 * cosine);
Scalar imag = (q2 * sine);
return std::complex<Scalar>(real, imag);
}
在哪里...
angle = std::arg(complex_number); // which is equivalent to atan2(imag, real);
magnitude = std::abs(complex_number); // again, same as sqrt(imag^2 + real^2);