[SciPy-user] Create a spectrogram from a waveform
Ed McCaffrey
ed at edmccaffrey.net
Sun Aug 31 14:58:23 EDT 2008
I've found what is creating the solid blue screen. That code gives a few
NaNs in the list, if I remove them then I get actual output.
However, I think that something is wrong if I am getting NaNs, and the
spectrogram just doesn't look right. Here is updated code:
from scipy import *
from pylab import *
from wave import *
import struct
wav = open('song.wav')
length = wav.getnframes()
tmp = [struct.unpack('f', wav.readframes(1))[0] for x in range(length)]
data = [x for x in tmp if isnan(x) == False]
spectrogram = specgram(data)
title('Spectrogram')
show();
On Sun, Aug 31, 2008 at 9:49 AM, Ed McCaffrey <ed at edmccaffrey.net> wrote:
> 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/086c1d35/attachment.html>
More information about the SciPy-User
mailing list