[SciPy-user] Create a spectrogram from a waveform

Peter Wang pwang@enthought....
Sat Aug 30 20:28:12 CDT 2008

Quoting Ed McCaffrey <ed@edmccaffrey.net>:

> I wrote a program in C# that creates a spectrogram from the waveform of a
> .wav music file.  I now want to port it to Python, and I want to try to use
> SciPy instead of a direct port of the existing code, because I am not sure
> that it is perfectly accurate, and it is probably slow.
> I am having a hard time finding out how to do this with SciPy.  With my
> code, I had a FFT function that took an array of real and imaginary
> components for each sample, and a second function taking both that produced
> the amplitude.  The FFT function in SciPy just takes one array.
> Has anyone done this task in SciPy?

We have a realtime spectrogram plot in the Audio Spectrum example for  
Chaco.  (See the very last screenshot on the gallery page here:  

You can see the full source code of the example here:

The lines you would be interested in are the last few:

def get_audio_data():
     pa = PyAudio()
     stream = pa.open(format=paInt16, channels=1, rate=SAMPLING_RATE,
     string_audio_data = stream.read(NUM_SAMPLES)
     audio_data  = fromstring(string_audio_data, dtype=short)
     normalized_data = audio_data / 32768.0
     return (abs(fft(normalized_data))[:NUM_SAMPLES/2], normalized_data)

Here we are using the PyAudio library to directly read from the sound  
card, normalize the 16-bit data, and perform an FFT on it.

In your case, since you are reading a WAV file, you might be  
interested in the zoomed_plot example:  

This displays the time-space signal but can easily be modified to show  
the FFT.  Here is the relevant code that uses the built-in python  
'wave' module to read the data:  

You should be able to take the 'data' array in the wav_to_numeric  
function and hand that in to the fft function.


More information about the SciPy-user mailing list