I'm trying to capture real time audio via loopback, in order to apply filters and play it back in real time. The idea is to filter in real time any audio being played on computer: audio files, web browsers, etc. Is it something that's even possible?
I've tried to capture loopback audio with pyaudio and play it back to output device, but it results in cracking noises and delay whenever I try to play something.
import numpy as np
import pyaudiowpatch as pyaudio
CHUNK_SIZE = 512
record = True
p=pyaudio.PyAudio()
try:
# Get default WASAPI info
wasapi_info = p.get_host_api_info_by_type(pyaudio.paWASAPI)
except OSError:
print("Looks like WASAPI is not available on the system. Exiting...")
# Get default WASAPI speakers
default_speakers = p.get_device_info_by_index(wasapi_info["defaultOutputDevice"])
if not default_speakers["isLoopbackDevice"]:
for loopback in p.get_loopback_device_info_generator():
"""
Try to find loopback device with same name(and [Loopback suffix]).
Unfortunately, this is the most adequate way at the moment.
"""
if default_speakers["name"] in loopback["name"]:
default_speakers = loopback
break
else:
print("Default loopback output device not found.\n\nRun `python -m pyaudiowpatch` to check available devices.\nExiting...\n")
stream= p.open(format=pyaudio.paInt16,
channels=default_speakers["maxInputChannels"],
rate=int(default_speakers["defaultSampleRate"]),
frames_per_buffer=CHUNK_SIZE,
input=True,
input_device_index=default_speakers["index"],
stream_callback=callback)
default_output_device = p.get_default_output_device_info()
# Open stream for output (to default input device)
output_stream = p.open(format=pyaudio.paInt16,
channels=default_output_device['maxOutputChannels'],
rate=int(default_output_device['defaultSampleRate']),
frames_per_buffer=CHUNK_SIZE,
output=True,
input_device_index=default_output_device["index"]
)
stream.start_stream()
output_stream.start_stream()
print(f"Recording from: ({default_speakers['index']}){default_speakers['name']}")
# Wait for KeyboardInterrupt
try:
while True:
# input_data = stream.read(CHUNK_SIZE)
## apply filter here
output_stream.write(input_data)
except KeyboardInterrupt:
pass
stream.stop_stream()
stream.close()
print("stopped")
output_stream.stop_stream()
output_stream.close()