I'm trying to plot fft in python. I use pyalsaaudio for capturing audio in PCM (S16_LE) format. I use the ion() and draw() functions in matplotlib to have the fft plotted in real time. This is the program I wrote :
import alsaaudio as alsa
import numpy as np
from matplotlib import pyplot as plot
from matplotlib import animation
import time
#Configuration
card = 'default'
audio = alsa.PCM(alsa.PCM_CAPTURE,alsa.PCM_NONBLOCK, card)
def configure():
plot.ion()
audio.setchannels(1)
audio.setrate(44100)
audio.setformat(alsa.PCM_FORMAT_S16_LE)
audio.setperiodsize(1000)
def run():
loops = 100000
plot.show()
while loops > 0 :
loops-=1
length,data = audio.read()
if length:
#converting into a float array
npdata = np.fromstring(data,dtype='<i2')
#Obtaining FFT
freq_list = np.fft.fft(npdata)
plot.plot(freq_list)
plot.draw()
plot.clf()
plot.close()
configure()
run()
1) The entire plot is jumpy. The y axis limits range from -5 t 5 to several tens of thousands. Since the range of y axis keeps changing, so does the location of the plot. How can I fix this?
2) The x axis range is the argument to audio.setperiodsize(). In this case, it is 1000. From the pyalsaaudio documentation, "When the hardware processes data this is done in chunks of frames. The time interval between each processing (A/D or D/A conversion) is known as the period". Hence period is something to do with the time domain. It should have no relevance in the plot since fft is in the frequency domain. So why does the x axis of my plot end at the period size?
3) I believe that the fft function returns a set of complex numbers. What do they mean? The real part signifies the frequency and the imaginary part the amplitude? When I call matplotlib.plot() on the set of fft values, what is being plotted actually?
4) My objective is to determine the dominant frequency of a signal. To do this, I need to know the frequency and the amplitude of the component with that particular frequency. Can I get this from the fft plot?
Thanks for looking into this.
plt_gain = plt.plot(freqs, zeros(len(freqs)))[0]
and then update the data points in the loop withplt_gain.set_data(freqs, gain)
$\endgroup$