有没有一种简单的方法可以找到声音信号中包络的频率?

2024-04-28 05:49:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个5秒长的声音信号,它来自螺旋桨的声音。我需要通过求包络线的频率来求出螺旋桨的转速

import wave
import numpy as np
import matplotlib.pyplot as plt

raw = wave.open('/content/drive/MyDrive/Demon.wav','r')
signal = raw.readframes(-1)
signal = np.frombuffer(signal , dtype="int16")
frate = raw.getframerate()

time = np.linspace(0,len(signal) / frate,num = len(signal))

plt.figure(1)
plt.title("Sound Wave")
plt.xlabel("Time")

plt.plot(time, signal)
plt.show()

下面是指向声音文件本身的链接:https://sndup.net/5v3j

由于它是一个5秒长的信号,有80.000个样本,我想通过观察信号的1秒部分来详细了解它

partial_signal = signal [1 : 16000]
partial_time = time[1 : 16000]
plt.plot(partial_time,partial_signal)
plt.show()

图的输出如下所示

Output

编辑:看起来图像不会显示此处是指向图像的链接: https://imgur.com/P5lnSM1 现在,我需要通过使用python来找到螺旋桨转速的频率


Tags: import声音rawsignallentime信号as
1条回答
网友
1楼 · 发布于 2024-04-28 05:49:46

通过对信号振幅应用快速傅里叶变换(FFT),可以很容易地做到这一点。以下是一个例子:

import wave
import numpy as np
import matplotlib.pyplot as plt
from scipy.fft import rfft, rfftfreq
from scipy.ndimage import gaussian_filter

raw = wave.open('Demon.wav','r')
signal = raw.readframes(-1)
signal = np.frombuffer(signal , dtype="int16")
frate = raw.getframerate()
time = np.linspace(0,len(signal) / frate,num = len(signal))


# Compute the amplitude of the sound signal
signalAmplitude = signal.astype(np.float64)**2

# Filter the signal to remove very short-timed amplitude modulations (<= 1 ms)
signalAmplitude = gaussian_filter(signalAmplitude, sigma=frate/1000)

# Compute the frequency amplitude of the FFT signal
tmpFreq = np.abs(rfft(signalAmplitude))

# Get the associated practical frequency for this signal
hzFreq = rfftfreq(signal.shape[0], d=1/frate)

finalFrequency = hzFreq[1+tmpFreq[1:].argmax()]
print(finalFrequency)


# Show sound frequency diagram
plt.xticks(np.arange(21))
plt.xlim([1, 20]) # Show only interesting low frequencies
plt.plot(hzFreq, tmpFreq)
plt.show()

频率图如下所示: enter image description here

最终检测到的频率为3.0 Hz,这与我们能听到的非常一致

相关问题 更多 >