【问题标题】:Python Frequency vs. Time GraphPython 频率与时间图
【发布时间】:2014-09-11 19:12:43
【问题描述】:

我正在尝试使用 Python 获取 .wav 文件的频率与时间关系图。目前我有绘制幅度与时间以及频率与功率(dB)的代码。我尝试使用频率与功率图的代码来绘制频率与时间,但未成功。我知道频率数据是对称的,这意味着与我的时间数据相比,我有 1/2 的数据点。我可以通过保留重复的频率数据来绘制它们,但我怀疑这是否真的产生了频率与时间的准确表示。

我觉得该方法将涉及对数据段使用短时傅立叶变换,然后绘制结果。也就是说,我发现了一些与此类似的代码,但我很难理解代码发生了什么,也很难做出任何有意义的调整来帮助我实现目标。

总之,我希望有人能提供一些示例代码或一种方法,用于在 Python 中创建 .wav 文件的频率与时间图。万分感谢!请让我知道我是否可以发布迄今为止我一直在使用的代码。

#Import the required functions
from scipy.io.wavfile import read
from scipy.fftpack import fft, fftfreq, fftshift
from scipy.signal import get_window
from math import ceil
from pylab import figure, imshow, clf, gray, xlabel, ylabel

# Read in a wav file 
#   returns sample rate (samples / sec) and data
rate, data = read('waveTest.wav')
data = data[:,0]
# Define the sample spacing and window size.
dT = 1.0/rate
T_window = 50e-3
N_window = int(T_window * rate)
N_data = len(data)

# 1. Get the window profile
window = get_window('hamming', N_window)

# 2. Set up the FFT
result = []
start = 0
while (start < N_data - N_window):
    end = start + N_window
    result.append(fftshift(fft(window*data[start:end])))
    start = end

result.append(fftshift(fft(window*data[-N_window:])))
result = array(result,result[0].dtype)

# Display results
freqscale = fftshift(fftfreq(N_window,dT))[150:-150]/1e3
figure(1)
clf()

s.imshow(abs(result[:,150:-150]), extent=(5,-5,(N_data*dT-T_window/2.0),T_window/2.0)) #19.04, -19.04, 6.41, 0.025 
s.xlabel('Frequency (kHz)')
s.ylabel('Time (sec.)')

s.show()

根据要求,上面是我正在尝试使用的代码。我实际上似乎让它工作正常,但我有几个问题。

1) abs(result[:,150:-150]) 到底是什么?我意识到他正在取傅里叶变换的绝对值(为了去除复杂的分量?)。这就是频率吗?

2) 我如何将数据交换为 X 轴上的时间和 Y 轴上的频率?

3) 图像如何知道哪个频率对应哪个时间?如果我理解正确,范围采用最后两个参数,即文件的时间长度和文件应该执行的步骤?

4) 是否可以在绘图而不是图像上绘制数据?

我希望这些问题不要太多,也不要太具体。再次感谢您提供的任何帮助!

【问题讨论】:

  • 请提供您想要修复的代码。
  • 以上贴,谢谢!

标签: python time graph wav frequency


【解决方案1】:

1) result[:,150:-150] 给出一个 numpy.array 包含所有行(每行对应于由 fft 计算的频率)和从 150number of columns - 150 的列。每列对应于时间。是的,abs 取给定频率的绝对值,大致对应于信号的频率。

2) 在abs(result[:,150:-150]) 中,您需要转置矩阵,如下所示:abs(result[:,150:-150]).transpose()

3) 范围参数指定最终图中的范围。由于每一列都对应于特定的时间点,因此它是一个简单的映射。

4)您获得的数据是给定频率在给定时间对信号的贡献程度(给定时间窗口,因为特定点的频率没有意义)。它本质上是二维数据。您可以尝试在给定时间找到主导频率,然后将其绘制为一个简单的函数。

您的代码也不起作用。也许你错过了一些变量定义和你程序其余部分的导入。

【讨论】:

    猜你喜欢
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 2019-07-21
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多