【发布时间】:2018-08-17 05:17:08
【问题描述】:
我正在尝试查找人们在 wav 文件中讲话的频谱,但在此之前,我想我会尝试仅使用一个简单的 200hz 音频文件来执行此操作。在下面的代码中,我读入了 200hz 文件并将其绘制在屏幕上。 注意:200hz 文件的采样率为 192000。我的块大小是 1/10,所以每 19200 个样本
from scipy.io import wavfile
import numpy as np
### This is just for drawing
import matplotlib.pyplot as plt
import matplotlib.animation as animation
### Above is for drawing
# Read the .wav file
sample_rate, data = wavfile.read('200hz.wav')
CHUNK_SAMPLES_PER_SECOND = 10
CHUNK = sample_rate / CHUNK_SAMPLES_PER_SECOND
# Now compute the spectrum on a given frame
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
# Now, lets just draw the plot
for frame in range(len(data) / CHUNK):
ax1.clear()
frame_data = data[frame * CHUNK:(frame + 1) * CHUNK, 0] # normally 2 channel, take 1st channel
frame_data = frame_data * 1.0 / frame_data.max()
#### Below, activate those to use the FFT ####
# frame_data = np.fft.fft(frame_data) # Calculate FFT on dataset
# frame_data = frame_data * 1.0 / frame_data.max() # Normalize FFT data
# ax1.set_xlabel('frequency')
ax1.plot(np.abs(frame_data), '-')
ax1.set_xlabel('sample')
ax1.set_ylabel('volume')
plt.pause(1.0 / CHUNK_SAMPLES_PER_SECOND)
以上代码产生:
对我来说,这看起来是正确的。由于我仅以 192000 的采样率采集 19200 个样本,因此该图应为 0.1 秒。因此,一个 200 Hz 的信号应该有大约 20 个全波。
当我通过取消注释来启用以下代码时:
#### Below, activate those to use the FFT ####
# frame_data = np.fft.fft(frame_data) # Calculate FFT on dataset
# frame_data = frame_data * 1.0 / frame_data.max() # Normalize FFT data
# ax1.set_xlabel('frequency')
它会生成一个看起来很时髦的 fft 图表:
我猜我预计它会显示一个大约 200hz 的峰值,或者至少是信号频率的一个明确定义的峰值。谢谢!
编辑: 我添加了我使用的实际音频文件here。
我还将 Y 轴调整为对数刻度,X 轴范围如下:
【问题讨论】:
-
您是否尝试放大 x 轴的 0-400 范围?那是应该采取行动的地方!另外,对 y 使用对数轴。
-
看起来不错,只是真的缩小了。如果放大左侧尖峰,您应该会看到一个大的 FFT 箱。如果您使用
numpy.fft.fftfreq以赫兹为单位制作一个真实的频率轴并与之对照,则该尖峰应为 200 Hz。右尖峰应为192000-200Hz。如果您发布您的 WAV 文件,我们可以独立确认。 -
@CrisLuengo 啊 - 好点!我放大了图表(见上文),我认为我得到了一些更好的结果,如你所见。山峰似乎不在正确的位置?当我达到 10 个代表时,我会内联图像:(
-
@AhmedFasih 感谢您的回复!我尝试为绘图功能添加
ax1.plot(np.fft.fftfreq(len(frame_data)), np.abs(frame_data)),但它产生了上面列出的结果。