Skip to content

Instantly share code, notes, and snippets.

@denisb411
Created May 3, 2017 12:39
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save denisb411/cbe1dce9bc01e770fa8718e4f0dc7367 to your computer and use it in GitHub Desktop.
Save denisb411/cbe1dce9bc01e770fa8718e4f0dc7367 to your computer and use it in GitHub Desktop.
Real time microphone analysis. Real time plot of signal and FFT using numpy, matplotlib and pyaudio
import pyaudio
import numpy as np
import time
import wave
import matplotlib.pyplot as plt
# open stream
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
CHUNK = 2048 # RATE / number of updates per second
RECORD_SECONDS = 20
# use a Blackman window
window = np.blackman(CHUNK)
x = 0
def soundPlot(stream):
t1=time.time()
data = stream.read(CHUNK, exception_on_overflow=False)
waveData = wave.struct.unpack("%dh"%(CHUNK), data)
npArrayData = np.array(waveData)
indata = npArrayData*window
#Plot time domain
ax1.cla()
ax1.plot(indata)
ax1.grid()
ax1.axis([0,CHUNK,-5000,5000])
fftData=np.abs(np.fft.rfft(indata))
fftTime=np.fft.rfftfreq(CHUNK, 1./RATE)
which = fftData[1:].argmax() + 1
#Plot frequency domain graph
ax2.cla()
ax2.plot(fftTime,fftData)
ax2.grid()
ax2.axis([0,5000,0,10**6])
plt.pause(0.0001)
print("took %.02f ms"%((time.time()-t1)*1000))
# use quadratic interpolation around the max
if which != len(fftData)-1:
y0,y1,y2 = np.log(fftData[which-1:which+2:])
x1 = (y2 - y0) * .5 / (2 * y1 - y2 - y0)
# find the frequency and output it
thefreq = (which+x1)*RATE/CHUNK
print "The freq is %f Hz." % (thefreq)
else:
thefreq = which*RATE/CHUNK
print "The freq is %f Hz." % (thefreq)
if __name__=="__main__":
p=pyaudio.PyAudio()
stream=p.open(format=pyaudio.paInt16,channels=1,rate=RATE,input=True,
frames_per_buffer=CHUNK)
plt.ion()
fig = plt.figure(figsize=(10,8))
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)
for i in range(0, RATE / CHUNK * RECORD_SECONDS):
soundPlot(stream)
stream.stop_stream()
stream.close()
p.terminate()
@adityanandgaokar
Copy link

I am getting this error :-
waveData = wave.struct.unpack("%dh"%(chunk), data)
struct.error: unpack requires a buffer of 8192 bytes
Please help me

@othmar52
Copy link

othmar52 commented Mar 7, 2020

struct.error: unpack requires a buffer of XXXX bytes

@adityanandgaokar i got the same error in a similar situation.
the variable CHUNK is 2048 and due to the error message 8192 bytes are required. So multiplying by 4 helped in my case

waveData = wave.struct.unpack("%dh"%(CHUNK*4), data)

@czenon1
Copy link

czenon1 commented Dec 15, 2021

Hi, you forgot something line 49 and +, try this :
thefreq = (which+x1)*RATE/CHUNK print("The freq is %f Hz." % (thefreq)) else: thefreq = which*RATE/CHUNK print ("The freq is %f Hz." % (thefreq))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment