[Numpy-discussion] Re: Code Question

Robert Kern robert.kern at gmail.com
Sat Apr 15 12:00:06 CDT 2006


Saqib bin Sohail wrote:
> Hi guys
> 
> I have never used python, but I wanted to compute FFT of audio files, I came
> upon a page which had python code, so I installed Numpy but after beating the
> bush for a few days, I have finally come in here to ask. After taking the FFT I
> want to output it to a file and the use gnuplot to plot it.
> When I instaled NumPy, and ran the tests, it seemed that all passed without a
> problem. My input is a .dat file converted from .wav file by sox.
> 
> Here is the code which obviously doesn't work because it seems that changes
> have occured since this code was written. (not my code, just from some website
> where a guy had written on how to do things which i require)

Okay, first some history. Originally, the package was named Numeric;
occasionally, it was referred to by its nickname NumPy. Some years ago, a group
needed features that couldn't be done in the Numeric codebase, so they started a
rewrite called numarray. For various reasons that I don't want to get into,
another group needed features that couldn't be done in the numarray codebase, so
a second rewrite happened and this package is the one that is currently getting
the most developer attention. It is called numpy.

Since you are a new user, I highly recommend that you use numpy instead of
Numeric or numarray.

  http://numeric.scipy.org/

> import Numeric
> import FFT
> out_array=Numeric.array(out)
> out_fft=FFT.fft(out)
> 
> offt=open('outfile_fft.dat','w')
> for x in range(len(out_fft)/2):
>     offt.write('%f %f\n'%(1.0*x/wtime,abs(out_fft[x].real)))

Rewritten for numpy (but untested):

import numpy
# Assuming that the file contains 32-bit floats, and not 64-bit floats
data = numpy.fromfile('test.dat', dtype=numpy.float32)
out_fft = numpy.refft(data)
# Note: refft does the FFT on real data and thus throws away the negative
# frequencies since they are redundant. len(out_fft) != len(data)

# and now I'm confused because the code references variables that weren't
# created anywhere, so I'm going to output the power spectrum

n = len(out_fft)
freqs = numpy.arange(n, dtype=numpy.float32) / len(data)
power = out_fft.real*out_fft.real + out_fft.imag*out_fft.imag
outarray = numpy.column_stack(freqs, power)
assert outarray.shape == (n, 2)

offt = open('outfile_fft.dat', 'w')
try:
  for f, p in outarray:
    offt.write('%f %f\n' % (f, p))
finally:
  offt.close()

> I do the following at the python prompt
> 
> import numarray
> myFile = open('test.dat', 'r')
> my_array = numarray.arra(myFile)
> 
> /* at this stage I wanted to see if it was correctly read */
> 
> print myArray
> [1632837691 1701605485 1952535072 ...,  538976288  538976288  168632368]
> 
> it seems that these values do not correspond to the values in the file (but I
> guess the array is considering these as ints when infact these are floats)

Indeed. There is no way for the array constructor to know the data type in the
file unless if you tell it. The default type is int.

-- 
Robert Kern
robert.kern at gmail.com

"I have come to believe that the whole world is an enigma, a harmless enigma
 that is made terrible by our own mad attempt to interpret it as though it had
 an underlying truth."
  -- Umberto Eco





More information about the Numpy-discussion mailing list