I am trying to follow this method of comparing .wav files, but am getting the following warnings:
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)
I examine what's happening and find that mult
is set to the following:
[[ 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]]
As instructed by the answer on dsp.stackexchange, I am zero-padding my data. Is this causing infinities? How can I multiply a list of complex values?
UPDATE: I have changed it to "manually" multiply like so:
mult = [i*j for (i, j) in itertools.izip(fft1, fft2)]
and am getting fewer nan-inf
s, but still a few. It now is producing the following warnings:
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)]
but it seems to be closer. Any thoughts?
UPDATE 2
Of course I had forgotten the kluge way I'm unpacking the wav chunks. I did a sys.getsizeof(frames[0])
to find that the size of each element is 36. Code here:
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
The problem most likely lie here: data = struct.unpack(">fdddd", frames[start:start+chunk_size])
. The string ">fdddd"
tells unpack to "get" little endian (>
) a four-byte float (f
) and four eight-byte doubles (d
). I most likely am misunderstanding the documentation.