gpt4 book ai didi

python - 在给定时间/样本量下,频率 f1 和 f2 之间呈指数变化的正弦波

转载 作者:太空狗 更新时间:2023-10-30 00:36:18 30 4
gpt4 key购买 nike

我正在尝试实现生成正弦波的 Python 方法,该正弦波在两个频率之间呈指数上升。[this question] 中解决了线性变化使用以下 Python 代码:

from math import pi, sin

def sweep(f_start, f_end, interval, n_steps):
for i in range(n_steps):
delta = i / float(n_steps)
t = interval * delta
phase = 2 * pi * t * (f_start + (f_end - f_start) * delta / 2)
print t, phase * 180 / pi, 3 * sin(phase)

sweep(1, 10, 5, 1000)

如何将这种线性累积相位/增量方法更改为指数频率扫描并使人耳平滑。

最佳答案

这类问题的诀窍是理解 frequency modulation 之间的关系和 phase modulation ,这两者是密切相关的。具有恒定频率 f 和幅度 A 的正弦可以描述为(公式,不是 python 代码):

x(t) = A sin(2 * pi * f * t)

但是另一种写法是首先定义一个阶段 phi 作为时间的函数:

phi(t) = 2 * pi * f * t
x(t) = A sin(phi(t))

这里需要注意的是,频率f是相位的导数,除以2*pi:f = d/dt(phi(t))/(2* pi).

对于频率随时间变化的信号,您可以类似地定义一个瞬时频率 f_inst:

x(t) = A sin(phi(t))
f_inst = d/dt(phi(t)) / (2*pi)

你想要做的与此相反,你有一个给定的瞬时频率(你的对数扫描),你需要将其转换为相位。由于推导的对立面是积分,因此您可以像这样计算适当的相位(仍然是公式):

phi(t) = 2 * pi * Integral_0_to_t {f_inst(t) dt}
x(t) = A sin(phi(t))

您在这里所做的是对信号(频率为零)进行某种相位调制以获得所需的瞬时频率。这在 numpy 中很容易做到:

from pylab import *
n = 1000 # number of points
f1, f2 = 10, 30 # frequency sweep range in Hertz

t = linspace(0,1,1000)
dt = t[1] - t[0] # needed for integration

# define desired logarithmic frequency sweep
f_inst = logspace(log10(f1), log10(f2), n)
phi = 2 * pi * cumsum(f_inst) * dt # integrate to get phase

# make plot
plot(t, sin(phi))
xlabel('Time (s)')
ylim([-1.2, 1.2])
grid()
show()

结果图像:

Logarithmic frequency sweep

但是(正如 Dave 提到的 dupe 中也提到的),您可能不需要对数扫描,而是指数扫描。您的耳朵对频率具有对数感知,因此平滑/线性音阶(想想钢琴上的琴键)因此呈指数间隔。这可以通过简单地重新定义您的瞬时频率 f_inst(t) = f1 * exp(k * t) 来实现,其中选择 k 使得 f_inst(t2 ) = f2

如果你想使用amplitude modulation同时,您可以简单地将公式中的 A 更改为时间相关的 A(t)

关于python - 在给定时间/样本量下,频率 f1 和 f2 之间呈指数变化的正弦波,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19771328/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com