python频谱分析

import numpy as np
import matplotlib.pyplot as pl


sampling_rate = 8000

fft_size = 512

# 首先定义了两个常数:sampling_rate, fft_size,分别表示数字信号的取样频率和FFT的长度.由于快速离散傅里叶算法的影响这里的N必须是2的整数次幂,也称为FFT_SIZE。如果你不是取的整数次,小于则信号补0,大于则信号截断.

t = np.arange(0, 1.0, 1.0/sampling_rate)

x = np.sin(2*np.pi*156.25*t)  + 2*np.sin(2*np.pi*234.375*t)

#取样时间数组t可以很方便地调用函数计算出波形数据,这里计算的是两个正弦波的叠加,一个频率是156.25Hz,一个是234.375Hz.

用取样时间数组t可以很方便地调用函数计算出波形数据,这里计算的是两个正弦波的叠加,一个频率是156.25Hz,一个是234.375Hz:
对于8KHZ取样,512点FFT来说,8000/512=15.625Hz,156.25Hz和234.375Hz正好是其10倍和15倍。

xs = x[:fft_size]

xf = np.fft.rfft(xs)/fft_size

#下面从波形数据x中截取fft_size个点进行fft计算。np.fft库中提供了一个rfft函数,它方便我们对实数信号进行FFT计算。根据FFT计算公式,为了正确显示波形能量,还需要将rfft函数的结果除以fft_size:

freqs = np.linspace(0, sampling_rate/2, fft_size/2+1)

#rfft函数的返回值是N/2+1个复数,分别表示从0(Hz)到sampling_rate/2(Hz)的N/2+1点频率的成分。于是可以通过下面的np.linspace计算出返回值中每个下标对应的真正的频率.N/2+1个。为什么?因为共轭对称。

xfp = 20*np.log10(np.clip(np.abs(xf), 1e-20, 1e100))

#最后我们计算每个频率分量的幅值,并通过 20*np.log10() 将其转换为以db单位的值。为了防止0幅值的成分造成log10无法计算,我们调用np.clip对xf的幅值进行上下限处理:

pl.figure(figsize=(8,4))
pl.subplot(211)
pl.plot(t[:fft_size], xs)
pl.xlabel(u"时间(秒)")
pl.title(u"156.25Hz和234.375Hz的波形和频谱")
pl.subplot(212)
pl.plot(freqs, xfp)
pl.xlabel(u"频率(Hz)")
pl.subplots_adjust(hspace=0.4)
pl.show()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值