[英]How to plot spectrum or frequency vs amplitude of entire audio file using python?
[英]Creating an amplitude vs frequency spectrogram of an audio file in Python
我正在尝试在Python中创建音频文件的幅度与频率频谱图。 这样做的程序是什么? 一些示例代码会很有帮助。
简单频谱
获得均匀采样信号x
的幅度与频率关系的最简单方法是通过高效的快速傅立叶变换算法计算其离散傅立叶变换 。 给定以常规采样率fs
采样的信号x
,您可以执行以下操作:
import numpy as np
Xf_mag = np.abs(np.fft.fft(x))
Xf_mag
数组的每个index
将包含一个频率仓的幅度,该频率仓的频率由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方法获得的频谱产生的频谱看起来非常嘈杂(即尖峰很多)。 为了获得更准确的估计,更复杂的方法是使用诸如周期图 (由scipy.signal.periodogram
实现)和Welch的方法 (由scipy.signal.welch
实现)等技术来计算功率谱估计 。 但是请注意,在这些情况下,计算出的频谱与振幅的平方成正比,因此其平方根可以提供均方根(RMS)振幅的估计值。
回到以常规采样率fs
采样的信号x
,这样就可以如scipy文档中的样本中所述获得功率谱估计,其中包括:
f, Pxx = signal.periodogram(x, fs)
A_rms = np.sqrt(Pxx)
相应的频率f
也会在此过程中计算出来,因此您可以用
plt.plot(f, A_rms)
使用scipy.signal.welch
非常相似,但是使用的实现略有不同,这提供了不同的精度/分辨率权衡。
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/generation/scipy.signal.spectrogram.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.