我想知道PortAudio PaStreamFinishedCallback
中哪些操作是安全的。我知道通常尝试阻止PaStreamCallback
播放的操作不是一个好主意,因为这可能会导致用户或其他应用程序的音频流出现弹出/故障。同样的限制适用于PaStreamFinishedCallback
吗?我想最终我很好奇是否也在操作系统的音频线程上调用了回调。
或者,是否有一个像Pa_StopStream
这样的函数会阻塞,直到回调返回paComplete
/ paAbort
,但不会导致停止?这实际上是我使用的理想选择,因为我有一个线程是我清理的正确位置。我知道我可以通过向我的线程发出回调信号来完成此操作,然后线程可以调用Pa_StopStream
,但感觉很重。
编辑:为了给我更多关于我的使用的上下文,我有一个环形缓冲区,它包含一些PCM并使用pthread condvar在缓冲区中有空间可用时发出信号。一个线程写入此环,然后PaStreamCallback
读出另一端。当事情结束时,作者在环上设置一个关闭的标志,然后回调消耗剩下的任何东西。我想确保我的戒指消失,而PortAudio正在冲洗。回调是唯一知道戒指何时消失的地方,因此返回paComplete
感觉合适。但是我需要一些方法来知道我的戒指可以解除分配。
答案 0 :(得分:0)
答案是,它很大程度上取决于主机,即使对于一台主机,行为也可能随时间而变化。我继续阅读实现,我在这里发现了一些有用的信息。
Pa_StopStream
只会调用主机系统的Stop()
行为。我没有阅读所有的实现,但可能大多数都有某种阻塞Stop()
。这意味着阻止停止而不实际请求停止将不太可能是受支持的行为。
PaStreamFinishedCallback
也只是主机自己的流停止回调的瘦包装器。例如,在OSX Core Audio中,这是Listener
上的kAudioOutputUnitProperty_IsRunning
。这完全取决于主机如何以及何时调用它。我认为这里的智能游戏应该尽可能谨慎 - 假设在这个回调中没有阻塞操作是安全的。
所以,如果你和我一样的情况,一个线程将PCM送入一个环形缓冲区,而PaStreamCallback
从该环读取,那么你可能想要
PaStreamFinishedCallback
PaStreamCallback
消耗它paComplete
返回PaStreamCallback
PaStreamFinishedCallback
pthread_cond_signal
发出工作完成的生产者线程的信号
甚至可以避免从音频线程发出信号(和锁定互斥锁),但很难想象还有其他选择。对于PCM环缓冲区的常规读取,PaStreamCallback
可能在放弃之前旋转一些有限次数。对于完成信号,生产者线程应该锁定然后立即等待,以便尽可能少地保持锁定。