我一直想使用 FFT 和频谱图来使用 python 来表征声音及其频率。
最近我在他的工作中记录了一只啄木鸟。
为了知道在哪里看,我将声音与Onlinegenerator.com生成的锯齿波进行了比较。我认为 17 Hz 很合适。
使用生成的文件检查代码效果很好。
但遗憾的是,我无法在 DFT/FFT 或使用以下代码生成的频谱图中找到频率。无论我尝试哪种设置,我都无法正确显示低于 20 Hz 的频率。没有主要信号切断或切断。只有 23 Hz 的信号,似乎是连续的。
from scipy import signal
import scipy.io.wavfile as wav
import matplotlib.pyplot as plt
import numpy as np
# Read WAV File
the_file = 'IMG_0710_short.wav'
samplerate, samples = wav.read(the_file)
#samples_left = samples[:,0]
samples = samples[:,1] # reduce to right channel
timevec = range(len(samples)) # Time vector for plot
timevec = [x / samplerate for x in timevec]
t_max =timevec[-1]
# Lineplot of Signal
dpi = 200
plt.rcParams['figure.dpi']= dpi
plt.plot(timevec,samples)
plt.title(the_file)
plt.ylabel('Amplitude [-]')
plt.xlabel('Time [sec]')
# STFT Settings
nperseg = 0.5 * samplerate # Window Size 1
noverlap = nperseg*0.95 # Overlap
nfft = 1 * samplerate # STFT 2
window = 'hann' # Window Type
timespan = [0, 2] # Calculation Window
fromm = int(len(samples)/t_max*timespan[0])
too = int(len(samples)/t_max*timespan[1])
f, t, Zxx = signal.stft(samples[fromm:too], samplerate, nperseg=nperseg, window=window, noverlap=noverlap, nfft=nfft)
t = t + timespan[0]
cmap=plt.cm.nipy_spectral
vmin = 10
vmax = 18
fig = plt.figure(figsize=(7, 5))
pcm = plt.pcolormesh(t, f, np.log(np.abs(Zxx)), cmap=cmap, vmin=vmin, vmax=vmax)
plt.ylim(0,50)
fig.colorbar(pcm)
plt.title(the_file)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
# FFT
n = len(samples) # length of the signal
k = np.arange(n)
T = n/samplerate
frq = k/T # two sides frequency range
frq = frq[range(int((n/2)))] # one side frequency range
Y = np.fft.fft(samples, norm='ortho')#/n # fft computing and normalization
Y = Y[range(int(n/2))]
fig, ax = plt.subplots(2, 1)
ax[0].plot(timevec,samples) # plotting the signal
ax[0].set_xlabel('Time')
ax[0].set_ylabel('Amplitude')
ax[1].plot(frq,abs(Y),'r') # plotting the spectrum
ax[1].set_xlabel('Frequency (Hz)')
ax[1].set_ylabel('|Y(freq)|')
ax[1].set_xlim(0,50)
我需要如何设置 stft 参数才能正确显示啄木鸟光谱?或者这里的 stft 是否存在根本问题?