平滑地连接来自输入的正弦波

Smoothly concatenating sine waves from input

上个月,我发布了 关于如何在生成正弦波时连接正弦波,但现在我遇到了不同的情况,我将生成一个正弦波并使其从末尾继续另一个我没有生成的正弦波。

我的解决方案基于我上一个问题的第二个答案,计算希尔伯特变换,然后用 numpy.angle 计算角度并通过添加 90 对其进行归一化,并从那里生成下一个正弦。它有效,但只有当我的频率值的单位是 0 或 5 时,否则,波不匹配,我不知道为什么。

from scipy.signal import hilbert
import numpy as np
from matplotlib import pyplot as plt

N = 1024
t = np.linspace(0, 1, N)
freq = 5.0

c = np.sin(2 * np.pi * freq * t + 0.0)
c2 = np.angle(hilbert(c), True)  # in degrees

plt.subplot(2, 1, 1)
plt.grid()
plt.plot(c)
plt.subplot(2, 1, 2)

phase = c2[-1] + 90

c3 = np.sin(2.0 * np.pi * freq * t + np.deg2rad(phase))

plt.grid()
plt.plot(c3)
plt.show()

频率:5.0

频率:5.8

当时间间隔开始和结束的值不一致时,就会出现边界效应,从而扭曲希尔伯特变换。 (回想一下,傅里叶变换对不连续性的反应很差。)这可以通过绘制 c2 的末端看出: plt.plot(c2[-200:] + 90):注意末端的失真,曲线应该以恒定斜率上升。

从时间边缘后退一段会得到更好的结果window:

phase = c2[-1 - int(N//freq)] + 90

我尝试使用频率 5.8:第二条曲线的开头与第一条曲线的结尾相匹配。

不清楚您的确切问题范围是什么。在上一个问题中,在引发此后续问题的评论中,您说:

If I don't have the generation equation ( say, I've got a chunk from mic ) what would be the approach?

这是否意味着数据不一定是正弦波?吵吗?它的大小不同吗?你提到 DSP:你是在实时进行处理,还是可以根据需要进行分析?


如果它是已知幅度的干净正弦波,则相对容易从信号末尾提取相位,以实现平滑延续。

阶段是sin⁻¹(y/mag)sin(angle) 有两个输入,其结果为 y/mag,一个用于 sin(angle) 随着 angle 的增加而增加,一个用于减少。通过查看上一点,我们可以确定我们需要哪一个。

def ending_phase(c, mag):
    angle = math.asin(c[-1] / mag)
    if c[-2] > c[-1]:
        angle = np.pi - angle
    return angle

从最后一个点的相位和倒数第二个点的相位,我们可以推断出下一个点的相位。

def next_phase(c, mag):
    ph1 = ending_phase(c[:-1], mag)
    ph2 = ending_phase(c, mag)
    return 2 * ph2 - ph1

将前一个块传递给 next_phase() 计算平滑地继续块所需的相位参数。

N = 1024
t = np.linspace(0, 1, N)

mag = 1.2
freq = 5.2
phase = 2.2
c1 = mag * np.sin(2 * np.pi * freq * t + phase)

plt.subplot(2,2,1)
plt.grid()
plt.plot(c1)


freq = 3.8
phase = next_phase(c1, mag)

c2 = mag * np.sin(2 * np.pi * freq * t + phase)
plt.subplot(2,2,2)
plt.grid()
plt.plot(c2)


c3 = np.concatenate((c1, c2))
plt.subplot(2,1,2)
plt.grid()
plt.plot(c3)


plt.show()