从 wav 文件 python 中提取频率

Posted

技术标签:

【中文标题】从 wav 文件 python 中提取频率【英文标题】:Extracting frequencies from a wav file python 【发布时间】:2016-12-06 13:32:15 【问题描述】:

我熟悉python,但对numpy很陌生,所以如果我错了,请原谅我。

我正在尝试读取具有多个频率(由静音分隔)的 .wav 文件。到目前为止,我已经能够读取这些值并在文件中找到有声音的各个部分。然后,我试图找到离散余弦变换并从中计算频率(参考:how to extract frequency associated with fft values in python)

但是,我收到一个错误:

索引 46392 超出轴 0 的范围,大小为 25

这是我的代码:

import wave
import struct
import numpy as np

def isSilence(windowPosition):
    sumVal = sum( [ x*x for x in sound[windowPosition:windowPosition+windowSize+1] ] )
    avg = sumVal/(windowSize)
    if avg <= 0.0001:
        return True
    else:
        return False

#read from wav file
sound_file = wave.open('test.wav', 'r')
file_length = sound_file.getnframes()
data = sound_file.readframes(file_length)
sound_file.close()
#data = struct.unpack("<h", data)
data = struct.unpack('nh'.format(n=file_length), data)
sound = np.array(data)
#sound is now a list of values

#detect silence and notes
i=0
windowSize = 2205
windowPosition = 0
listOfLists = []
listOfLists.append([])
maxVal = len(sound) - windowSize
while True:
    if windowPosition >= maxVal:
        break
    if not isSilence(windowPosition):
        while not isSilence(windowPosition):
            listOfLists[i].append(sound[windowPosition:windowPosition+ windowSize+1])
            windowPosition += windowSize
        listOfLists.append([]) #empty list
        i += 1
    windowPosition += windowSize

frequencies = []
#Calculating the frequency of each detected note by using DFT
for signal in listOfLists:
    if not signal:
        break
    w = np.fft.fft(signal)
    freqs = np.fft.fftfreq(len(w))
    l = len(signal)

    #imax = index of first peak in w
    imax = np.argmax(np.abs(w))
    fs = freqs[imax]

    freq = imax*fs/l
    frequencies.append(freq)

print frequencies

编辑:这是回溯:

Traceback (most recent call last):
  File "final.py", line 61, in <module>
    fs = freqs[imax]
IndexError: index 46392 is out of bounds for axis 0 with size 21

【问题讨论】:

" 我收到一个错误:..." 始终在您的问题中包含 complete 错误消息(即完整的回溯)。回溯显示哪一行触发了错误。 @WarrenWeckesser 好的。 fs = freqs[imax] 行导致了错误。在我上面提供的链接中,傅立叶变换是一维的。但是我的测试文件给出了一个多维列表。 可能是多声道(立体声)?如果是这样,通过取两个通道的平均值减少到单声道。 【参考方案1】:

问题是我假设listOfLists 实际上是一个列表列表,但实际上它是一个列表列表。行:

        listOfLists[i].append(sound[windowPosition:windowPosition+ windowSize+1])

每次都在附加一个列表,但我认为它是将元素附加到现有列表中。

例如,如果 listOfLists 是:

[ [1,2,3] ]

然后,listOfLists[0].append([4,5,6]) 将给出:

[ [ [1,2,3],[4,5,6] ] ]

但我期待:

[ [1,2,3,4,5,6] ]

用下面的代码替换有问题的行对我有用:

for v in sound[windowPosition:windowPosition+windowSize+1]:
            listOfLists[i].append(v)

【讨论】:

以上是关于从 wav 文件 python 中提取频率的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 python matplotlib 库从 wav 文件中提取数据?

Python从视频文件中提取wav

从mp4 python中提取wav

使用 python 从音频文件中提取 1/3 个八度音阶

从视频文件中提取wav文件

使用 JAVA 从 wav 文件中提取振幅数组