Python音频处理(一)——信号,波形与频谱

举报
择城终老 发表于 2021/07/27 00:02:30 2021/07/27
【摘要】 本文目录 前言波形频谱Spectrum 波形对象信号对象 前言 音频处理属于大学课程《多媒体技术》,什么采样率,频谱等理论知识,博主这里会慢慢的根据实际的代码进行讲解,不会一笼统的纯理论知识一大堆摆上来,毕竟学习音频处理是为了我们处理日常生活中的工作。 关于音频处理的方式,后面的代码都会使用python语言进行处理,至于学完后可以干啥,肯定是大家非...

前言

音频处理属于大学课程《多媒体技术》,什么采样率,频谱等理论知识,博主这里会慢慢的根据实际的代码进行讲解,不会一笼统的纯理论知识一大堆摆上来,毕竟学习音频处理是为了我们处理日常生活中的工作。

关于音频处理的方式,后面的代码都会使用python语言进行处理,至于学完后可以干啥,肯定是大家非常关系的,比如音乐的降噪,模拟某个人的声音,提取音频中重要的信息等,都可以通过python代码实现,话不多说我们直接开始介绍。

波形

在Python语言中, 波形的读写需要用到别人写好的thinkdsp.py代码,比如,这里我们需要读取一个音频并绘制其波形图,代码如下:

from matplotlib import pyplot
import thinkdsp

wave=thinkdsp.read_wave("aaa.wav")
wave.plot()
pyplot.show()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

三行代码就可以获取到某个音频文件的波形图,而绘制图形的代码属于matplotlib包,这段代码显示的效果如下图所示:
图形

频谱

通过thinkdsp读取进来的音频文件返回的Wave,提供了一个make_spectrum,spectrum就是频谱的意思,我们可以通过如下代码,打印出音频文件的频谱:

import thinkdsp
import thinkplot

wave=thinkdsp.read_wave("aaa.wav")
spectrum=wave.make_spectrum()
spectrum.plot()
thinkplot.show()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这段代码显示的效果如下图所示:
频谱

Spectrum

Spectrum提供了3中修改频谱的方法:

(1)low_pass:它加载一个低通滤波器,也就是说高于某个给定的截止频率的频率元素被按照一定因素衰减,也就是在大小上降低了。

(2)high_pass:它加载了一个高通滤波器,也就是说低于某个截止频率的元素被衰减了。

(3)band_stop:它让处于两个截止频率之间的波段内的频率元素衰减了。

比如,我们这里来看个例子,代码如下:

import thinkdsp
import thinkplot

wave=thinkdsp.read_wave("aaa.wav")
spectrum=wave.make_spectrum()
spectrum.low_pass(cutoff=600,factor=0.01)
spectrum.plot()
thinkplot.show()
wave=spectrum.make_wave()
wave.write("bbb.wav")


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这段代码会移除明亮的高频信号,所以其结果的声音比较压抑而且昏暗,使用低通滤波器后,得到的频谱如下:
对比读者可以对比一下上面两个图形的区别,上面最后两行代码是将spectrum转化成Wave,然后保存到bbb.wav文件中,读者可以试着代码听一下。

波形对象

thinkdsp.py里面并没有什么复杂的东西。其提供的大部分函数只是对Numpy和SciPy函数的稀薄封装。其中初始化的库包括Signal,Wave和Spectrum。给定Signal,读者就可以创建一个Wave。给定一个Wave,就可以创建一个Spectrum。Wave与Spectrum可以互相转换。

Wave对象包括3个特性:包括信号参数的Numpy数组ys;信号开始采用和取值的事件点数组ts;每单位时间的采样数framerate。时间的单位通常是秒,但也可以不是。

Wave还提供了三个只读属性:start,end和duration。如果修改了ts,这些属性也会变更。我们来看一段代码:

wave = thinkdsp.read_wave("aaa.wav")
#wave.scale(2)
#wave.shift(1)
wave.ys *= 2
wave.ts += 1
wave.write("bbb.wav")

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

上面的代码时将波形扩大两倍,晚一秒时间播放,注释的代码与ys,ts那两行代码是等价的,没有任何不同。

信号对象

Signal是一个父类,它向各种信号提供通用的函数,比如make_wave。子类继承了这些方法并提供evaluate,也就是在给定的时间序列内对信号取值。例如,Sinusoid是Signal的子类,定义如下:

class Sinusoid(thinkdsp.Signal): def __init__(self, freq=400, amp=1.0, offset=0, func=np.sin): thinkdsp.Signal.__init__() self.freq = freq self.amp = amp self.offset = offset self.func = func

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

参数的含义如下:

(1)freq:频率,其含义为每秒周期数,单位是Hz。

(2)amp:幅度。幅度的单位比较随意,通常设定为1.0,对应为传声器的最大输入或给扬声器的最大输出

(3)offset:其含义为信号周期的起始。offset的单位为弧度。

(4)func:它是一个python函数,用来指定时间点的信号求值。通常它不是np.sin就是np.cos,对应的分别是正弦信号和余弦信号。

跟很多初始化的方法一样,它也是把参数存起来以备未来使用。Signal提供了make_wave,如下所示:

def make_wave(self,duration=1,start=0,framerate=11025):
	n=round(duration*framerate)
	ts=start+np.arange(n)/framerate
	ys=self.evaluate(ts)
	return Wave(ys,ts,framerate=framerate)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

start和duration分别表示开始的时间和持续的时间,单位为秒.framerate是每秒帧率(采样数)。n代表采样的数量,而ts是采样时间的Numpy数组。为了计算ys,make_wave需要引入evaluate,它是由Sinusoid提供的:

def evaluate(self,ts):
	phases=PI*self.freq*ts+self.offset
	ys=self.amp*self.func(phases)
	return ys

  
 
  • 1
  • 2
  • 3
  • 4

下面我们来逐步地解析这个函数:

(1)self.freq是频率,代表每秒周期数,而ts的各个元素都是以秒计的,所以它们的乘积是从其实时间开始的周期数。

(2)PI2是一个常数,也是常用圆的Π,这里为2Π。乘上PI2之后就把周期转换成了相位。读者可以把相位理解为弧度形式的“从其实时间开始的周期数”,而每个周期的弧度为2Π。

(3)self.offset是t=0时刻的相位,其作用是把信号在时域上向左或者向右移动一定的距离。

(4)如果self.func是np.sin或者np.cos,其值便是出于-1到1之间。

(5)乘上self.amp之后产生的信号范围为-self.amp到self.amp。

在数学意义上,evaluate的公式如下:

y=Acos(2πft+φ0)

其中A是幅度,f是频率,t是时间,φ0是相位偏移。上面的代码其实就是这段表达式的值,但是正如我们将要看到的,这段代码提供了处理所有信号的构架,而不仅是三级函数信号的。

第一篇的内容就介绍到这里,我们用到的thinkdsp以及thinkplot代码可以在这里下载,下载地址如下:点击下载

文章来源: liyuanjinglyj.blog.csdn.net,作者:李元静,版权归原作者所有,如需转载,请联系作者。

原文链接:liyuanjinglyj.blog.csdn.net/article/details/104701036

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。