我希望在异步环境中使用PyAudio
库,但该库的主要入口只有基于回调的API:
import pyaudio
def callback(in_data, frame_count, time_info, status):
# Do something with data
pa = pyaudio.PyAudio()
self.stream = self.pa.open(
stream_callback=callback
)
我的希望是能够像这样使用它:
pa = SOME_ASYNC_COROUTINE()
async def listen():
async for block in pa:
# Do something with block
问题是,我不确定如何将这个回调语法转换为在回调触发时完成的future。在JavaScript中,我会使用promise.promisify()
,但Python似乎没有类似的东西。
make_iter()
改用类来实现,因为我最初很难理解它是一个返回函数元组的函数。 - Migwellcall_soon_threadsafe
就是为这种情况设计的。它会在不破坏事件循环的情况下(例如,在没有持有正确锁的情况下破坏其数据结构)将函数安排到事件循环中,并在事件循环在此期间处于休眠状态时唤醒它。 - user4815162342call_soon
来满足自身需求)。但即使没有破坏风险,如果不使用线程安全变量,事件循环也不会被唤醒,因为它不知道需要唤醒。典型的症状是存在一个无关的心跳协程可以“修复”问题,例如这个问题。 - user4815162342sounddevice
模块创建了一个示例:https://github.com/spatialaudio/python-sounddevice/blob/master/examples/asyncio_generators.py。这似乎运行得非常好! - Matthias