我正在从WAV文件中获得峰值频率
我从wav文件获取峰值频率的代码是:
import wave
import struct
import numpy as np
import wave
import contextlib
if __name__ == '__main__':
fname = "test.wav"
frate = 0
data_size = 0
with contextlib.closing(wave.open(fname,'r')) as f:
frate = f.getframerate()
data_size = f.getnframes()
wav_file = wave.open(fname, 'r')
data = wav_file.readframes(data_size)
data_size = data_size * wav_file.getnchannels()
print wav_file.getparams()
wav_file.close()
data = struct.unpack('{n}h'.format(n=data_size), data)
data = np.array(data)
w = np.fft.fft(data)
freqs = np.fft.fftfreq(len(w))
print(freqs.min(), freqs.max())
# Find the peak in the coefficients
idx = np.argmax(np.abs(w))
freq = freqs[idx]
freq_in_hertz = abs(freq * frate)
print(freq_in_hertz)
我录制了一个wav文件,采样率为48000、16位宽,2个通道。在那个文件中,我有一个1000Hz的正弦音。但是脚本仅输出500Hz。我不知道我哪里出了错。但是对于单通道和生成的具有48000采样率,16位宽,2个通道的wav文件,它工作正常。
我使用以下脚本生成了wav文件
import math
import wave
import struct
if __name__ == '__main__':
# http://stackoverflow.com/questions/3637350/how-to-write-stereo-wav-files-in-python
# http://www.sonicspot.com/guide/wavefiles.html
freq = 1000
data_size = 454656 * 2
fname = "test.wav"
frate = 48000.0
amp = 64000.0
nchannels = 2
sampwidth = 2
framerate = int(frate)
nframes = data_size
comptype = "NONE"
compname = "not compressed"
data = [math.sin(2 * math.pi * freq * (x / frate))
for x in range(data_size)]
wav_file = wave.open(fname, 'w')
wav_file.setparams(
(nchannels, sampwidth, framerate, nframes, comptype, compname))
for v in data:
wav_file.writeframes(struct.pack('h', int(v * amp / 2)))
wav_file.close()
我不知道我做错了什么。我将wav文件上传到脚本生成的wav script_gen.wav上,具有48000采样率,2通道,16位。录制的WAV:2通道WAV,采样率为48000,2通道,16位1通道WAV(不允许在此处发布链接,因此将在评论中发布),具有48000采样率,1通道,16位。
我大胆检查了所有这些峰值频率,它只显示了1000Khz。
但是当我尝试脚本时,我得到了1通道波形的正确输出,而2通道波形的输出却失败了。
更新:我得到的峰值频率的一半作为2个通道的输出。
我感觉自己错过了一些东西。有人可以帮我吗?
我认为这将对您有所帮助。只是添加了一些其他东西来配合您的外观。使用了MaxPowers逻辑。您需要将24位数据转换为32位,然后这也将适用于24位。
import sys
import wave
import struct
import numpy as np
import wave
import argparse
def parse_arguments():
"""Parses command line arguments."""
parser = argparse.ArgumentParser(description='Tool to get peak frequency')
parser.add_argument('fname', metavar='test.wav', type=str,
help='Path to a wav file')
args = parser.parse_args()
return args
def main():
args = parse_arguments()
fname = args.fname
wav_file = wave.open(fname, 'r')
frate = wav_file.getframerate()
data_size = wav_file.getnframes()
data = wav_file.readframes(data_size)
nChannels = wav_file.getnchannels()
nSample = wav_file.getsampwidth()
data_size = data_size * nChannels * nSample
wav_file.close()
if nSample == 2:
fmt = "<i2"
else :
fmt = "<i4"
data = np.frombuffer(data,dtype=fmt)
if nChannels == 2 :
data = data.reshape(-1,nChannels)
data = data.sum(axis=1) / 2
# and now the same way as above as said by maxpowers
freq_nq = len(data) // 2
X= abs(np.fft.fft(data))[:freq_nq] / len(data) * 2
freqs = np.fft.fftfreq(len(data), 1./frate)[:freq_nq]
print freqs[np.argmax(X)]
if __name__ == '__main__':
try:
main()
except (Exception) as e:
print str(e)
sys.exit(255)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句