簡體   English   中英

在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM