在Python中创建音频文件的幅度与频谱图

时间:2018-03-14 01:58:00

标签: python audio transform fft spectrogram

我正在尝试用Python创建音频文件的幅度与频谱图。这样做的程序是什么? 一些示例代码会有很大的帮助。

2 个答案:

答案 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