Realtime Spectrum Analyser using Python | Part-1

A Spectrum Analyser measures the amplitude or the magnitude of the input signal, with respect to the frequency. Its mainly used to analyse the amplitude of signals at different frequencies.

Python is a high level interpreted, multipurpose programming language. If you ever wanted to build your own audio spectrum analyser, that works out of the box with your microphone in Windows, linux or Mac, you are at the right place.

A realtime spectrum analyser doesn’t have any build time or lag. The analyser is able to sample the incoming spectrum in the time domain and convert the sampled information into frequency domain.

The algorithm that we will be using to convert the time domain signal to frequency domain is called FFT. Briefly, fast fourier transform. The Numpy’s fft library for Python is used to generate the fft for the python spectrum analyser or the python audio audio visualizer.

Libraries Required for python spectrum analyser / audio visualizer

For the first part of the video, where we sample the audio from the microphone and display it in the time domain. We will be needing the following Python Libraries.

  1. Numpy
    Numpy is a Python Library that adds support for large, multi-dimentional arrays and matrices. It has high level mathematical functions to operate on the data.
  2. PyAudio
    PyAudio is another Python Library that can be easily used to play and record audio with Python on a variety of platforms.
  3. Struct
    Struct is another Python module that performs conversion between Python values and C structures. It basically performes conversion of data from binaries to their equivalent python data types.
  4. MatPlotLib
    Matplotlib is a library for the Python and its numerical mathematics extension NumPy. It provides an object-oriented API for embedding plots into applications using general-purpose GUI toolkits like Tkinter, wxPython, Qt, or GTK+.

Installing Libraries

Installing the required libraries is very simple.
To install Numpy, run the following command in CLI

pip install numpy

Installing MatPlotLib and PyAudio is done in the same way.

pip install PyAudio
pip install matplotlib

If you face any problem installing PyAudio, download the .whl file based on your Python version and system architecture from here, and then run the command

pip install /path_to_whl_file/filename.whl

The Struct module comes pre-installed with Python.

The code

As always in Python we start off with importing the required libraries.

Skip the explination and jump to the complete code.

import numpy as np
import pyaudio as pa 
import struct 
import matplotlib.pyplot as plt 

Then, we initialize some variables.
CHUNK is the number of samples that will be processed and displayed at any instance of time.
FORMAT is the data type that the PyAudio library will output.
CHANNELS is the number of channels our microphone has.
RATE is the sampling rate. We will chose the most common one, that is 44100Hz or 44.1KHz.

CHUNK = 1024 * 2
FORMAT = pa.paInt16
CHANNELS = 1
RATE = 44100 # in Hz

Next we create a PyAudio object from class PyAudio and store it in a variable p.

p = pa.PyAudio()

Then, we use the open method on the object p and pass on the variables we initialiszed as parameters.

stream = p.open(
    format = FORMAT,
    channels = CHANNELS,
    rate = RATE,
    input=True,
    output=True,
    frames_per_buffer=CHUNK
)

Now, we will initiallise the plot with random values and set the limits for each of the two axises.

fig,ax = plt.subplots()
x = np.arange(0,2*CHUNK,2)
line, = ax.plot(x, np.random.rand(CHUNK),'r')
ax.set_ylim(-32770,32770)
ax.ser_xlim = (0,CHUNK)
fig.show()

Finally, we create an infinite loop and read the data from the microphone, convert the data into 16-bit numbers and further plot it using the matplotlib.pyplot function.

while 1:
    data = stream.read(CHUNK)
    dataInt = struct.unpack(str(CHUNK) + 'h', data)
    line.set_ydata(dataInt)
    fig.canvas.draw()
    fig.canvas.flush_events()

Now when you run the code. You should be able to see the program running flawlessly. If you encounter any error, check the default input device in your sound settings.

The complete code

import numpy as np 
import pyaudio as pa 
import struct 
import matplotlib.pyplot as plt 

CHUNK = 1024 * 2
FORMAT = pa.paInt16
CHANNELS = 1
RATE = 44100 # in Hz

p = pa.PyAudio()

stream = p.open(
    format = FORMAT,
    channels = CHANNELS,
    rate = RATE,
    input=True,
    output=True,
    frames_per_buffer=CHUNK
)



fig,ax = plt.subplots()
x = np.arange(0,2*CHUNK,2)
line, = ax.plot(x, np.random.rand(CHUNK),'r')
ax.set_ylim(-60000,60000)
ax.ser_xlim = (0,CHUNK)
fig.show()

while 1:
    data = stream.read(CHUNK)
    dataInt = struct.unpack(str(CHUNK) + 'h', data)
    line.set_ydata(dataInt)
    fig.canvas.draw()
    fig.canvas.flush_events()

This completes the part one. Feel free to comment and discuss.
Want to learn how to create and setup your own Blynk server to get started with IoT ?
Or want to know how I created this website? Do care to give a thumbs up and share.😄