-
-
Save netom/8221b3588158021704d5891a4f9c0edd to your computer and use it in GitHub Desktop.
#!/usr/bin/env python | |
# -*- charset utf8 -*- | |
import pyaudio | |
import numpy | |
import math | |
import matplotlib.pyplot as plt | |
import matplotlib.animation | |
RATE = 44100 | |
BUFFER = 882 | |
p = pyaudio.PyAudio() | |
stream = p.open( | |
format = pyaudio.paFloat32, | |
channels = 1, | |
rate = RATE, | |
input = True, | |
output = False, | |
frames_per_buffer = BUFFER | |
) | |
fig = plt.figure() | |
line1 = plt.plot([],[])[0] | |
line2 = plt.plot([],[])[0] | |
r = range(0,int(RATE/2+1),int(RATE/BUFFER)) | |
l = len(r) | |
def init_line(): | |
line1.set_data(r, [-1000]*l) | |
line2.set_data(r, [-1000]*l) | |
return (line1,line2,) | |
def update_line(i): | |
try: | |
data = numpy.fft.rfft(numpy.fromstring( | |
stream.read(BUFFER), dtype=numpy.float32) | |
) | |
except IOError: | |
pass | |
data = numpy.log10(numpy.sqrt( | |
numpy.real(data)**2+numpy.imag(data)**2) / BUFFER) * 10 | |
line1.set_data(r, data) | |
line2.set_data(numpy.maximum(line1.get_data(), line2.get_data())) | |
return (line1,line2,) | |
plt.xlim(0, RATE/2+1) | |
plt.ylim(-60, 0) | |
plt.xlabel('Frequency') | |
plt.ylabel('dB') | |
plt.title('Spectrometer') | |
plt.grid() | |
line_ani = matplotlib.animation.FuncAnimation( | |
fig, update_line, init_func=init_line, interval=0, blit=True | |
) | |
plt.show() |
awesome, thanks for the starting point for a project of mine!
You're welcome. It's nice to know that it's useful for somebody else too. :)
Sounds nice :)
Thanks for this, useful code, I'm sure it will be the starting point of many a good project. Most all other examples I've found are out of date and non-functional. Thanks for this!
Thank you @m1zar, it's always good to hear positive feedback :)
In python 3.9, I keep getting an error at startup saying that data is undefined:
"in update_line
np.real(data)**2+np.imag(data)**2) / BUFFER) * 10
UnboundLocalError: local variable 'data' referenced before assignment"
@netom I have similar problems as @thecompoundingdev. After tinkering around, it seemed this first error was the OSX microphone access. Still now the next error seems to be related to numpy and the spectrometer values. I tinkered around but could not solve this, do you have any idea what could be wrong?
...
File "/Users/lony/Desktop/dump/audio_filter/./spectrum.py.py", line 46, in update_line
line2.set_data(np.maximum(line1.get_data(), line2.get_data()))
ValueError: operands could not be broadcast together with shapes (2,) (2,2206)
I use the followng versions
❯ python --version
Python 3.9.6
❯ cat requirements.txt
matplotlib==3.4.3
numpy==1.21.2
PyAudio==0.2.11
@netom any chance you have an example with an logarithmic frequency axis? I am not able to get it to work using semilogx etc.
Revision 2 is compatible with Python 3