In order to decrease the CPU Usage on Sounddevice with Asyncio, I have tried to put time.sleep(0.1) on while loop, but this throws me a "_queue.Empty" error.
Is there any possible way I can fix this issue?
If it is not possible, is there any other way to decrease the cpu usage on my code?
Any hint or suggestion will be great
Thanks.
Code :
# Libraries
import sounddevice as sd
import numpy as np
import time
import queue
import asyncio
async def stream_generator(input_device_index, output_device_index):
"""Generator that yields blocks of input/output data as NumPy arrays.
The output blocks are uninitialized and have to be filled with
appropriate audio signals.
"""
block_shift = 128
q_in = asyncio.Queue()
q_out = queue.Queue()
loop = asyncio.get_event_loop()
def callback(indata, outdata, frame_count, time_info, status):
loop.call_soon_threadsafe(q_in.put_nowait, (indata.copy(), status))
outdata[:] = q_out.get_nowait()
# pre-fill output queue
for _ in range(10):
q_out.put(np.zeros((block_shift, 1), dtype=np.float32))
stream = sd.Stream(device=(input_device_index, output_device_index), samplerate=16000,
blocksize=block_shift, latency=0.2, callback=callback, dtype=np.float32, channels=1)
with stream:
while True:
indata, status = await q_in.get()
outdata = np.empty((block_shift, 1), dtype=np.float32)
yield indata, outdata, status
q_out.put_nowait(outdata)
#time.sleep(0.1) # I wish to put sleep here for the optimizing cpu usage.
async def wire_coro(input_device_index, output_device_index):
"""Create a connection between audio inputs and outputs.
Asynchronously iterates over a stream generator and for each block
simply copies the input data into the output block.
"""
async for indata, outdata, status in stream_generator(input_device_index, output_device_index):
if status:
print(status)
outdata[:] = indata
async def main(input_device_index, output_device_index):
audio_task = asyncio.create_task(wire_coro(input_device_index, output_device_index))
for i in range(10, 0, -1):
print(i)
await asyncio.sleep(1)
audio_task.cancel()
if __name__ == "__main__":
print(sd.query_devices())
try:
asyncio.run(main(1, 4)) # please put input parameters accordingly what sd.query_devices says!
except KeyboardInterrupt:
sys.exit('\nInterrupted by user')
Error : error screenshot