Skip to content

Instantly share code, notes, and snippets.

@ZWMiller
Created June 19, 2017 16:36
Show Gist options
  • Star 28 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save ZWMiller/53232427efc5088007cab6feee7c6e4c to your computer and use it in GitHub Desktop.
Save ZWMiller/53232427efc5088007cab6feee7c6e4c to your computer and use it in GitHub Desktop.
Using Python to plot the current microphone's input and the Fourier Transform
try:
import pyaudio
import numpy as np
import pylab
import matplotlib.pyplot as plt
from scipy.io import wavfile
import time
import sys
import seaborn as sns
except:
print "Something didn't import"
i=0
f,ax = plt.subplots(2)
# Prepare the Plotting Environment with random starting values
x = np.arange(10000)
y = np.random.randn(10000)
# Plot 0 is for raw audio data
li, = ax[0].plot(x, y)
ax[0].set_xlim(0,1000)
ax[0].set_ylim(-5000,5000)
ax[0].set_title("Raw Audio Signal")
# Plot 1 is for the FFT of the audio
li2, = ax[1].plot(x, y)
ax[1].set_xlim(0,5000)
ax[1].set_ylim(-100,100)
ax[1].set_title("Fast Fourier Transform")
# Show the plot, but without blocking updates
plt.pause(0.01)
plt.tight_layout()
FORMAT = pyaudio.paInt16 # We use 16bit format per sample
CHANNELS = 1
RATE = 44100
CHUNK = 1024 # 1024bytes of data red from a buffer
RECORD_SECONDS = 0.1
WAVE_OUTPUT_FILENAME = "file.wav"
audio = pyaudio.PyAudio()
# start Recording
stream = audio.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True)#,
#frames_per_buffer=CHUNK)
global keep_going
keep_going = True
def plot_data(in_data):
# get and convert the data to float
audio_data = np.fromstring(in_data, np.int16)
# Fast Fourier Transform, 10*log10(abs) is to scale it to dB
# and make sure it's not imaginary
dfft = 10.*np.log10(abs(np.fft.rfft(audio_data)))
# Force the new data into the plot, but without redrawing axes.
# If uses plt.draw(), axes are re-drawn every time
#print audio_data[0:10]
#print dfft[0:10]
#print
li.set_xdata(np.arange(len(audio_data)))
li.set_ydata(audio_data)
li2.set_xdata(np.arange(len(dfft))*10.)
li2.set_ydata(dfft)
# Show the updated plot, but without blocking
plt.pause(0.01)
if keep_going:
return True
else:
return False
# Open the connection and start streaming the data
stream.start_stream()
print "\n+---------------------------------+"
print "| Press Ctrl+C to Break Recording |"
print "+---------------------------------+\n"
# Loop so program doesn't end while the stream callback's
# itself for new data
while keep_going:
try:
plot_data(stream.read(CHUNK))
except KeyboardInterrupt:
keep_going=False
except:
pass
# Close up shop (currently not used because KeyboardInterrupt
# is the only way to close)
stream.stop_stream()
stream.close()
audio.terminate()
@alikrc
Copy link

alikrc commented Aug 7, 2018

print function must be used with braces according to python 3 so it gives error

@odcowl
Copy link

odcowl commented Nov 29, 2018

Hey, this code is very useful except for when each time I try to run it, first at all, it did show the figure,
but later my computer juste shut down the figure, I tried to change de Record sounds but it doesn't change anything.
Did anyone have de same problem as I ?

@landa
Copy link

landa commented Jul 15, 2019

Hey, this code is very useful except for when each time I try to run it, first at all, it did show the figure,
but later my computer juste shut down the figure, I tried to change de Record sounds but it doesn't change anything.
Did anyone have de same problem as I ?

I had the same problem as you. It would show two frames of the FFT and then freeze.

If you remove the try catch block at the bottom, you see that this code raises an "Input Overflow" pyaudio Exception. If I pass an argument to stream.read called exception_on_overflow set to False (and add parentheses to all of the print statements), then this code works for me.

@Erimitis-1926
Copy link

One issue that I keep encountering is that every time that I record and plot real-time audio input signals I get some small repetitive gaps in the recording due to the plotting delay. If you simply store the streaming audio in the above code and then store is as a wave file you'll notice small gaps, which will disappear once you stop plotting the data. Any ideas on how to solve this? Multi-processing maybe?

@Vnaf
Copy link

Vnaf commented Mar 10, 2020

Hi

I'm trying to run this code but it freezes just after beginning, it seems to work, though, but just for a fraction of a second.

I tried to follow instructions on landa's comment but I don't know how to pass the argument to stream.read, I managed to remove the try block, and now it gives me the input overflow exception.

Any tips on this?

Thanks in advance

@landa
Copy link

landa commented Mar 10, 2020 via email

@Vnaf
Copy link

Vnaf commented Mar 10, 2020

Yes, I just found it, thanks!

@Am4dEuZ
Copy link

Am4dEuZ commented Jul 10, 2020

Line 87 plot_data(stream.read(CHUNK)) -->plot_data(stream.read(CHUNK, exception_on_overflow = False))

@Prabal1902
Copy link

Hey, this code is very useful except for when each time I try to run it, first at all, it did show the figure, but later my computer juste shut down the figure, I tried to change de Record sounds but it doesn't change anything. Did anyone have de same problem as I ?

Maybe try running the code without the "try:" block. As that block is used to check for errors in code, maybe not having any errors in the first place is causing the code to end.

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