[SciPy-user] Create a spectrogram from a waveform

Ed McCaffrey ed at edmccaffrey.net
Sun Aug 31 09:49:18 EDT 2008


Thanks for the replies.  I think that now I am heading towards the right
direction, but I have one problem.  When I run my program all I get for the
spectrogram is a solid blue graph.

The program is:

from scipy import *
from pylab import *
from wave import *
import struct

wav = open('song.wav')
length = wav.getnframes()

data = [struct.unpack('f', wav.readframes(1))[0] for x in range(length)]

spectrogram = specgram(data)
title('Spectrogram')

show();

I tried it with a few different short clips with the same result.  One of
them can be found: http://edmccaffrey.net/misc/song.wav


Thanks.



On Sat, Aug 30, 2008 at 9:28 PM, Peter Wang <pwang at enthought.com> wrote:

> Quoting Ed McCaffrey <ed at 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:
> http://code.enthought.com/projects/chaco/gallery.php)
>
> You can see the full source code of the example here:
>
> https://svn.enthought.com/enthought/browser/Chaco/trunk/examples/advanced/spectrum.py
>
> 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,
>                      input=True,
>                      frames_per_buffer=NUM_SAMPLES)
>     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:
> http://code.enthought.com/projects/chaco/pu-zooming-plot.html
>
> 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:
>
> https://svn.enthought.com/enthought/browser/Chaco/trunk/examples/zoomed_plot/wav_to_numeric.py
>
> You should be able to take the 'data' array in the wav_to_numeric
> function and hand that in to the fft function.
>
>
> -Peter
>
> _______________________________________________
> SciPy-user mailing list
> SciPy-user at scipy.org
> http://projects.scipy.org/mailman/listinfo/scipy-user
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.scipy.org/pipermail/scipy-user/attachments/20080831/51e25409/attachment.html>


More information about the SciPy-User mailing list