上个月,我发布了this question关于如何在生成正弦波时进行级联,但是现在我遇到了另一种情况,我将生成正弦波并使其从另一个正弦波的末尾继续我没有生成。
我的解决方案基于上一个问题的第二个答案,计算希尔伯特变换,然后,使用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
答案 0 :(得分:2)
当时间间隔的开始和结束时的值不一致时,将出现边界效应,使希尔伯特变换变形。 (回想一下,傅立叶变换对不连续性的反应很差。)这可以通过绘制c2
:plt.plot(c2[-200:] + 90)
的末端来看出:注意失真朝着末端,曲线应该以恒定的斜率上升。
从时间窗口的边缘向后退一个周期,您将获得更好的结果:
phase = c2[-1 - int(N//freq)] + 90
我尝试使用频率5.8:第二条曲线的起点与第一条曲线的终点匹配。
答案 1 :(得分:1)
目前尚不清楚您的确切问题范围是什么。在上一个问题中,产生此后续问题的评论中,您说:
如果我没有生成方程式(例如,我从mic中得到了很大一部分),那将是什么方法?
这是否意味着数据不一定是正弦波?吵吗它大小不一吗?您提到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()