平滑串联来自输入的正弦波

时间:2018-07-10 05:44:52

标签: python numpy scipy signal-processing

上个月,我发布了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

Frequency of 5.0, match

频率:5.8

Frequency of 5.8, miss

2 个答案:

答案 0 :(得分:2)

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

bad

从时间窗口的边缘向后退一个周期,您将获得更好的结果:

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

我尝试使用频率5.8:第二条曲线的起点与第一条曲线的终点匹配。

match

答案 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()

enter image description here