我正在尝试用Python创建音频文件的幅度与频谱图。这样做的程序是什么? 一些示例代码会有很大的帮助。
答案 0 :(得分:2)
简单光谱
获得均匀采样信号x
的幅度与频率关系的最简单方法是通过有效的Discrete Fourier Transform算法计算其Fast Fourier Transform。如果以常规采样率x
采样信号fs
,您可以执行以下操作:
import numpy as np
Xf_mag = np.abs(np.fft.fft(x))
index
数组的每个Xf_mag
将包含频率仓的幅度,其频率由index * fs/len(Xf_mag)
给出。可以使用以下方法方便地计算这些频率:
freqs = np.fft.fftfreq(len(Xf_mag), d=1.0/fs)
最后,可以使用matplotlib绘制光谱:
import matplotlib.pyplot as plt
plt.plot(freqs, Xf_mag)
完善频谱估算
您可能会注意到,使用简单FFT方法获得的频谱会产生一个看起来很嘈杂的频谱(即有很多尖峰)。
为了获得更准确的估算,更复杂的方法是使用诸如power spectrum estimate(由periodograms实现)和scipy.signal.periodogram
(由{{实现)等技术来计算Welch's method 3}})。但请注意,在这些情况下,计算出的频谱与幅度的平方成正比,因此其平方根提供了均方根(RMS)幅度的估计。
回到以常规采样率x
采样的信号fs
,可以如scipy的文档样本中所述获得这样的功率谱估计,具体如下:
f, Pxx = signal.periodogram(x, fs)
A_rms = np.sqrt(Pxx)
相应的频率f
也会在此过程中计算出来,因此您可以使用
plt.plot(f, A_rms)
使用scipy.signal.welch
非常相似,但使用略有不同的实现,提供了不同的准确度/分辨率权衡。
答案 1 :(得分:1)
from scipy import signal
import matplotlib.pyplot as plt
fs = 10e3
N = 1e5
amp = 2 * np.sqrt(2)
noise_power = 0.01 * fs / 2
time = np.arange(N) / float(fs)
mod = 500*np.cos(2*np.pi*0.25*time)
carrier = amp * np.sin(2*np.pi*3e3*time + mod)
noise = np.random.normal(scale=np.sqrt(noise_power), size=time.shape)
noise *= np.exp(-time/5)
x = carrier + noise
f, t, Sxx = signal.spectrogram(x, fs)
plt.pcolormesh(t, f, Sxx)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()
这是从scipy文档中提取的,因为您需要科学计算才能创建谱图。 如果您还没有安装scipy,请阅读它的文档:
https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.spectrogram.html