78 lines
1.8 KiB
Python
78 lines
1.8 KiB
Python
|
#!/usr/bin/env nix-script
|
||
|
#!>python
|
||
|
#! python | matplotlib numpy scipy pyaudio
|
||
|
|
||
|
## Real-time sound spectrum analysis.
|
||
|
|
||
|
import pyaudio
|
||
|
import scipy.fftpack
|
||
|
import scipy.interpolate
|
||
|
import numpy
|
||
|
import pylab
|
||
|
|
||
|
#pyAudio settings
|
||
|
settings = {
|
||
|
"format": pyaudio.paInt16,
|
||
|
"channels": 2,
|
||
|
"rate": 96000,
|
||
|
"input": True,
|
||
|
"frames_per_buffer": 1024
|
||
|
}
|
||
|
audio = pyaudio.PyAudio()
|
||
|
stream = audio.open(**settings)
|
||
|
|
||
|
#pyLab configurations
|
||
|
pylab.ion()
|
||
|
figura, (spectrum_log, spectrum, wave) = pylab.subplots(nrows=3, ncols=1)
|
||
|
pylab.subplots_adjust(hspace=0.5, left=0.1)
|
||
|
|
||
|
#Plot settings
|
||
|
spectrum_log.set_ylabel("a (dB)")
|
||
|
spectrum_log.set_xlabel("ƒ (Hz)")
|
||
|
spectrum_log.ticklabel_format(style="sci", scilimits=(0, 0), axis="x")
|
||
|
spectrum_log.grid(True)
|
||
|
curve1, = spectrum_log.plot([0, 8 * 10 ** 3], [0, 10 ** 2], "b-")
|
||
|
|
||
|
spectrum.yaxis.set_visible(False)
|
||
|
spectrum.set_xlabel("ƒ (Hz)")
|
||
|
spectrum.ticklabel_format(style="sci", scilimits=(0, 0), axis="x")
|
||
|
spectrum.grid(True)
|
||
|
curve2, = spectrum.plot([0, 8 * 10 ** 3], [0, 10 ** 5])
|
||
|
|
||
|
wave.xaxis.set_visible(False)
|
||
|
wave.yaxis.set_visible(False)
|
||
|
curve3, = wave.plot([0, 8 * 10 ** 3], [-2 * 10 ** 3, 2 * 10 ** 3], "g-")
|
||
|
|
||
|
#Main loop
|
||
|
while True:
|
||
|
#Acquire data from microphone
|
||
|
try:
|
||
|
block = numpy.array(numpy.fromstring(
|
||
|
stream.read(settings["frames_per_buffer"]), dtype="int16"))
|
||
|
except IOError:
|
||
|
continue
|
||
|
|
||
|
#FFT of registred block
|
||
|
fftx = scipy.fftpack.rfftfreq(
|
||
|
settings["frames_per_buffer"],
|
||
|
1 / settings["rate"])
|
||
|
|
||
|
#Calculate log version
|
||
|
ffty = abs(scipy.fftpack.fft(block)[0:len(fftx)])
|
||
|
ffty_log = 10 * scipy.log10(ffty)
|
||
|
|
||
|
#Data interpolation
|
||
|
wave = scipy.interpolate.interp1d(fftx, block[0:len(fftx)])(fftx)
|
||
|
|
||
|
#Update plot data
|
||
|
curve1.set_xdata(fftx)
|
||
|
curve2.set_xdata(fftx)
|
||
|
curve3.set_xdata(fftx)
|
||
|
|
||
|
curve1.set_ydata(ffty_log)
|
||
|
curve2.set_ydata(ffty)
|
||
|
curve3.set_ydata(wave)
|
||
|
|
||
|
#Redraw
|
||
|
pylab.draw()
|