2

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-infs, 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.

Will
  • 4,299
  • 5
  • 32
  • 50
  • 1
    Are you sure you are converting the data from the WAV correctly. Secondly, why do you want to deal with nan/inf, why not just use a larger data type. – Clarus Jun 25 '15 at 23:36
  • What is current datatype of your array? Just use a larger-one (e.g. `complex128` or `complex256` ). – rth Jun 26 '15 at 04:43

1 Answers1

0

OP Solution: As @rth and @Claris guess I was unpacking my data incorrectly. Running sys.getsizeof() on the elements of frames led me to believe that each element had to be unpacked in 36-byte chunks.

As indicated in another answer (which I lost ): ), I had to unpack the frames in smaller chunks:

data = struct.unpack(">fdddd", frames[start:start+chunk_size])

I changed to:

data = struct.unpack(">H", frames[start:start+chunk_size])

And I changed chunk_size from 36 to 2. The element-wise multiplication is working fine now, no NaNs or Infs.

See more on struct.unpack().

Will
  • 4,299
  • 5
  • 32
  • 50