专栏总目录
本章了解多种波形,观察频谱理解他们的谐波结构,也就是构成他们的三角函数稽核的结构。
介绍数字信号处理中最重要的现象之一:混叠,同时解释Spectrum类的工作原理
2.1 三角波
一个正弦波,仅包含一个频率元素,所以其频谱只有一个尖峰。
复杂波形,例如,下图小提琴录音片段,其离散傅里叶变换的结果中有很多尖峰。
本章继续研究波形和频谱之间的关系。
从三角波开始,三角波就像是正弦波的直线版本。图2-1显示的三角波的频率是200Hz。
图 2-1 200Hz的三角波片段
2.1.1 创建TriangleSignal类
可以使用thinkdsp.TriangleSignal生成三角波:
class TriangleSignal(Sinusoid):
def evaluate(self, ts):
# 获得周期数
cycles = self.freq * ts + self.offset / PI2
# 获取周期数的小数部分,忽略整数部分
frac, _ = np.modf(cycles)
# 减小振幅
ys = np.abs(frac - 0.5)
# unbias——将波形中心放置0的位置
# normalize最大化波形(音量)
ys = normalize(unbias(ys), self.amp)
return ys
TriangleSignal从Sinusoid继承了__init__,所以它们使用的参数是一样的,都有freq、amp和offset。
唯一的差别在于evalute。如我们在前面看到过的,ts是我们相对信号求值的采样时间的序列。
产生三角波的方法很多。其细节并不重要,但是我们需要知道evaluate的工作原理:
1. cycles是自起始时间的周期数。np.modf是将周期的数量分解成小数部分和整数部分,前者被存于frac,后者被忽略了。
2. frac序列介于0~1,其频率是给定的。减去0.5之后其值介于-0.5~0.5。对其取绝对值就得到了在0~0.5穿梭的波形。
3.unbias将波形下移,使得其中心位于0,然后normalize将波形归一化到给定的振幅amp。
2.3.2 创建三角波信号
以下是产生图2-1的代码(可以在jupyter notebook中直接运行获得下图):
from thinkdsp import TriangleSignal
from thinkdsp import decorate
# 创建三角波信号
signal = TriangleSignal(200)
# 截取三个周期
duration = signal.period*3
# 创建wave数据
segment = signal.make_wave(duration, framerate=10000)
#图形化数据
segment.plot()
decorate(xlabel='Time (s)')
如果在idle或.py文件中执行,需要在上述脚本下面追加代码:
#将上面数据保存成图像trianglesignal.png
plt.savefig('trianglesignal.png')
2.3.3 获取三角波声音
如果想要听到该声音:
将上述三角波转换为声音数据
# 获得采样率10000,持续时间0.5秒的波形数据 wave = signal.make_wave(duration=0.5, framerate=10000) # 音量最大化 wave.normalize() # 淡入淡出 wave.apodize()
jupyter notebook上直接执行即可
# 播放 wave.make_audio()
如果在idle或.py文件中执行,需要在转换为声音数据之后追加如下代码:
# 保存音频为WAV文件 from scipy.io.wavfile import write scaled = np.int16(wave.ys/np.max(np.abs(wave.ys)) * 32767) write('output.wav', wave.framerate, scaled) # 现在,您可以使用音频播放器打开并播放output.wav文件。
2.3.4 获取三角波频谱
使用上面的signal创建wave,从而使用创建的wave来生成spectrum:
(jupyter notebook中可以直接运行下方代码)
spectrum = wave.make_spectrum()
spectrum.plot()
decorate(xlabel='Frequency (Hz)')
&n