I created a python coding that apply HPF to the input audio in real-time. It works just fine.
import pyaudio
import time
import numpy as np
from scipy.signal import firwin, firwin2, lfilter, freqz
WIDTH = 2
CHANNELS = 2
RATE = 44100
p = pyaudio.PyAudio()
f1 = 500/1000
def bytes_to_float(byte_array):
int_array = np.frombuffer(byte_array, dtype=np.float32)
return int_array
def float_to_bytes(float_array):
int_array = float_array.astype(np.float32)
return int_array.tostring()
def callback(in_data, frame_count, time_info, flag):
signal = bytes_to_float(in_data)
a = [1]
b = firwin(129, f1, pass_zero=False)
filtered= lfilter(b, a, signal)
output = float_to_bytes(filtered)
return (output, pyaudio.paContinue)
stream = p.open(format=pyaudio.paFloat32,
channels=CHANNELS,
rate=RATE,
output=True,
input=True,
stream_callback=callback)
stream.start_stream()
while stream.is_active():
time.sleep(0.1)
stream.stop_stream()
stream.close()
p.terminate()
Now, I wanted to display the frequency spectrum of filtered audio. So, I edited the python coding above.
from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import time
import pyqtgraph as pg
import pyaudio
from scipy.signal import firwin, firwin2, lfilter, freqz
app = QtGui.QApplication([])
win = pg.GraphicsWindow(title="Basic plotting examples")
win.resize(1000,600)
win.setWindowTitle('pyqtgraph example: Plotting')
pg.setConfigOptions(antialias=True)
p6 = win.addPlot(title="Updating plot")
p6.setYRange(-100, 20)
curve = p6.plot(pen='y')
chunks = 1024
freq = np.linspace(1e-6, (chunks / 2), chunks, endpoint=True)
def bytes_to_float(byte_array):
int_array = np.frombuffer(byte_array, dtype=np.float32)
return int_array
def float_to_bytes(float_array):
int_array = float_array.astype(np.float32)
return int_array.tostring()
def update_freq_plot(x):
global curve, freq
h = 20 * np.log10(np.abs(np.fft.rfft(x, n=2 * chunks)[:chunks]))
curve.setData(x=freq, y=h, clear=True)
def update():
WIDTH = 2
CHANNELS = 2
RATE = 44100
p = pyaudio.PyAudio()
f1 = 500/1000
def callback(in_data, frame_count, time_info, flag):
signal = bytes_to_float(in_data)
a = [1]
b = firwin(129, f1, pass_zero=False)
z = np.zeros(129 - 1)
filtered, z = lfilter(b, a, signal, zi=z)
update_freq_plot(filtered)
output = float_to_bytes(filtered)
return (output, pyaudio.paContinue)
stream = p.open(format=pyaudio.paFloat32,
channels=CHANNELS,
rate=RATE,
output=True,
input=True,
stream_callback=callback)
stream.start_stream()
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(20)
## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
I used this as a reference. When I run the coding, it does display the spectrum, but it is lagging. I'm using jupyter to run the coding.
I would like to ask how to improve my coding so that the lagging issue won't appear? Any help is much appreciated. Thank you.