我正在尝试按照this比较.wav文件的方法,但收到以下警告:
valid:call.py:23: RuntimeWarning: overflow encountered in multiply
mult = numpy.multiply(fft1, fft2)
call.py:23: RuntimeWarning: invalid value encountered in multiply
mult = numpy.multiply(fft1, fft2)
我检查发生了什么,发现mult
设置如下:
[[ inf -0.j nan-infj nan+infj ..., nan+infj nan-infj nan+infj]
[ inf -0.j -inf+nanj inf+nanj ..., -inf+nanj inf+nanj -inf+nanj]
[ inf -0.j nan-infj inf+nanj ..., nan-infj inf+nanj nan+infj]
...,
[ inf -0.j -inf+nanj -inf+nanj ..., -inf+nanj -inf+nanj -inf+nanj]
[ inf -0.j -inf+nanj -inf+nanj ..., -inf+nanj -inf+nanj -inf+nanj]
[ inf -0.j nan-infj nan-infj ..., nan+infj nan+infj nan+infj]]
根据dsp.stackexchange上的答案,我对数据进行了零填充。这会导致无穷大吗?如何将复数值列表相乘?
更新:我已将其更改为“手动”倍增,如下所示:
mult = [i*j for (i, j) in itertools.izip(fft1, fft2)]
我的nan-inf
越来越少,但仍有一些。它现在产生以下警告:
valid:call.py:26: RuntimeWarning: overflow encountered in cdouble_scalars
mult = [i*j for (i, j) in itertools.izip(a, b)]
call.py:26: RuntimeWarning: invalid value encountered in cdouble_scalars
mult = [i*j for (i, j) in itertools.izip(a, b)]
但它似乎更接近了。有什么想法吗?
更新2
当然,我已经忘记了解开wav块的方式。我做了一个sys.getsizeof(frames[0])
来发现每个元素的大小是36.代码在这里:
def get_fft(fft_path):
return_list = []
frames_list = []
chunk_size = 36
start = 0
wav = wave.open(fft_path, 'r')
frames = wav.readframes(wav.getnframes())
wav.close()
while start+chunk_size < len(frames):
data = struct.unpack(">fdddd", frames[start:start+chunk_size])
frames_list.extend(data)
start += chunk_size
if len(frames_list) >= 1000:
frames_list.extend(numpy.zeros(len(frames_list)))
return_list.append(numpy.fft.fft(frames_list))
frames_list = []
return return_list
问题最有可能在于:data = struct.unpack(">fdddd", frames[start:start+chunk_size])
。字符串">fdddd"
告诉unpack“get”小端(>
)一个四字节的浮点数(f
)和四个八字节的双精度数(d
)。我很可能误解了documentation。
答案 0 :(得分:0)
OP解决方案:由于@rth和@Claris猜测我正在正确地解压缩数据。在sys.getsizeof()
的元素上运行frames
让我相信每个元素都必须以36个字节的块进行解压缩。
如另一个答案所示(我丢失了):),我不得不用较小的块解压缩帧:
data = struct.unpack(">fdddd", frames[start:start+chunk_size])
我改为:
data = struct.unpack(">H", frames[start:start+chunk_size])
我将chunk_size
从36更改为2.元素方式的乘法现在正常工作,没有NaN
s或Inf
s。
有关struct.unpack()的更多信息,请参阅