赞
踩
分享一下我用Python模拟的AM,PM,FM调制,起因就是刚开始了解调制的时候,有点理解不了,那模拟一下呗,然后就写了一个代码。
代码地址
先放一个AM的演示图
然后看一个程序调用,我不喜欢奇奇怪怪的操作,程序调用要符合操作逻辑:创建信息波和载波,然后生成调制信号波,最后画图。
fig = plt.figure() # 创建画布 # 初始化波的参数:频率和幅度 A = 2 # carrier wave amplitude m = 1 # m is the amplitude sensitivity mes_fre = 1 # message wave frequence car_fre = 10 # carrier wave frequence # 创建信息波 signal = Signal() mes_wave = SinWave(fre=mes_fre, Amp=A*m, Phi=0) information_signal = signal + mes_wave # 创建载波 carrier_signal = CosWave(fre=car_fre, Amp=A, Phi=0) # 创建时间轴 time = np.arange(0, 2*np.pi, 0.01) # 生成调制信号 am_sig = AM(information_signal, carrier_signal, A=A) # 画出动图 ud = UpdateDist(fig, time, information_signal, carrier_signal, am_sig) ani = animation.FuncAnimation(fig=fig, func=ud, frames=20, interval=100, blit=True) plt.show()
我比较喜欢模块化应用,我在网上也调研了一部分的模拟代码,发现大多是一次性的工作,基本没有移植性。所以我就按照我的思想写了一个脚本,虽然代码会显得有点臃肿,但是移植性还是蛮不错的。接下来就分享一下我的思路,我不会讲调制的原理,就讲代码的实现方式。
模拟的是调制,调制也就是两个信号的相互作用。信号也就是波的叠加,简化一下,载波(carrier wave)用单一频率的波表示,信号波(message wave)用波实现简单运算得到。这个时候还有点复杂,波的种类繁多,所以我就只考虑Sin和Cos波。对应到代码构造,我比较喜欢用类编程,于是就有了下面的结构
class Wave: def __init__(self, fre, Amp, Phi): # 定义波的公共属性:幅度、频率、相位 pass def __str__(self): # 打印波的信息,方便后期调试 pass class SinWave(Wave): # 继承 Wave 类,子类实现 波与波的乘法运算 def __init__(self, fre, Amp, Phi, modu_wave=None): super().__init__(fre, Amp, Phi, modu_wave, info='Sin') def __call__(self, t): # 定义调用接口,实现将t带入运算 pass def __mul__(self, scalar): # 定义 波与波 之间的乘法运算法则 pass def __rmul__(self, scalar): # 也是 实现 波与波的运算 pass class CosWave(Wave): # 构造与 SinWave 类似,不同的只是乘法运算法则不同 class Signal: def __init__(self, sig=None): # 初始化 "Signal", 可以是 Wave 也可以是 实数,内部用 list 保存 pass def max_fre(self): # 获取 Signal 的最大频率 pass def max_Amp(self): # 获取 Signal 的最大幅值 pass def __iter__(self): # 使得 Signal 变为可迭代对象,满足 Signal*Wave的运算 pass def __add__(self, sig): # Signal 满足加法运算 pass def __radd__(self, sig): # Signal 满足加法运算 pass def __call__(self, t): # Signal 满足可调用 pass def __str__(self): # 打印 Signal 的信息,方便以后调试。 pass
信号Signal
和波Wave
初始化完成后,需要考虑调制的函数。这里用3个函数表示三种调制就行了
def AM(information_signal, carrier_signal, A):
# AM 幅度调制,A 是调幅的参数,参考AM调制的原理
pass
def PM(information_signal, carrier_signal):
# PM 相位调制
pass
def FM(information_signal, carrier_signal, h=1):
# FM 频率调制,h是调频参数 参考FM调制的原理
pass
创建画图类 UpdateDist
class UpdateDist:
# 画动图时候推荐采用类编程,比函数好管理
def __init__(self, fig, x, *func_y):
# 初始化刚开始的图像显示,我这里初始化了三个波
pass
def __call__(self, i):
# 调用函数,这里的 i 也就是 t=i 时刻函数的图像,这样达到了动态显示的效果
pass
对代码的完善就是对上面框架的缝缝补补,有时候可能会修改框架,上面的框架是我推翻了一次原框架后的结果。不过上面的框架还是适用于 AM 调制,因为 AM 调制本质就是几个波的乘法运算,而 PM 和 FM 是修改了波的相位,于是我就加了一个 modu_wave
变量
class CosWave(Wave):
def __init__(self, fre, Amp, Phi, modu_wave=None):
# modu_wave 默认为 None ,如果 PM 和 FM 时需要传入
super().__init__(fre, Amp, Phi, modu_wave, info='Cos')
self.modu_wave = modu_wave
class SinWave(Wave):
def __init__(self, fre, Amp, Phi, modu_wave=None):
super().__init__(fre, Amp, Phi, modu_wave, info='Sin')
self.modu_wave = modu_wave
代码的具体实现,点击获取原文可以查看。
我在代码中用了几个 __mul__
、__add__
等以__
开头结尾的函数,这是python的魔法函数,它是python的一种协议。比如如果实现了函数 __add__
,就可以使用 +
运算。
__add__
和 __radd__
# 比如这里有两个波
test1_wave = CosWave(fre= 2, Amp=0.5, Phi=0)
test2_wave = CosWave(fre= 3, Amp=0.5, Phi=0)
# 实现了 __add__ 函数后 载波信号可以这么写
signal = Signal()
information_signal = signal + test1_wave + test2_wave
# 实现了 __radd__ 函数后,前后式子可以调换位置
information_signal = test1_wave + signal + test2_wave
# tip: 我这里只在 Signal 中实现了 + 法运算,所以 下面的写法会报错
# test_wave = test1_wave + test2_wave # 报错
# 原因嘛,我觉得 Signal 实现 + 就够使用了
可以看看波的样子
__mul__
和__rmul__
# __mul__ 表示乘法运算
# 还是上面的两个波,我可以直接这么写
information_signal = signal + test1_wave * test2_wave
# 同理 实现了 __rmul__ 后可以换位置
information_signal = signal + test2_wave * test1_wave
看看波的样子
__call__
# 实现 # call 函数后,类变量可以和函数一样调用
# 上面的波举例,我要是想知道 t=1 时函数的幅值我就可以这么写
A1 = test1_wave(1) # 0.5
A2 = test2_wave(1) # 0.5
__str__
# 实现函数后 可以使用 str(func) 打印函数
# 接着上面的例子, 程序结果放在 '#' 后面
print(test1_wave) # CosWave(Frequency is 2,Amplitude is 0.5,Initial phase is 0),modulate wave is None
print(test2_wave) # CosWave(Frequency is 2,Amplitude is 0.5,Initial phase is 0),modulate wave is None
以上就是我分享的这次代码的细节部分,点击阅读全文获取代码。最后放几个 PM 和 FM 调制的图,我曾经对着这个图呆了一早上。
代码地址
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。