PortAudio的PaStreamFinishedCallback上的安全操作

问题描述 投票:0回答:1

我想知道PortAudio的PaStreamFinishedCallback中哪些操作是安全的。我知道通常尝试阻止PaStreamCallback播放的操作不是一个好主意,因为这可能会导致用户或其他应用程序的音频流出现弹出/故障。同样的限制是否适用于PaStreamFinishedCallback?我想最终我很好奇是否也在OS的音频线程上调用了该回调。

或者,是否有像Pa_StopStream这样的函数会阻塞,直到回调返回paComplete / paAbort,但没有引发停止?这实际上是我使用的理想选择,因为我有一个线程是我清理的正确位置。我知道我可以通过向我的线程发出回调信号来完成此操作,然后线程可以调用Pa_StopStream,但感觉很重。

编辑:为了给我更多关于我的使用的上下文,我有一个环形缓冲区,它包含一些PCM并使用pthread condvar在缓冲区中有空间可用时发出信号。一个线程写入此环,然后PaStreamCallback读出另一端。当事情结束时,作者在环上设置一个关闭的标志,然后回调消耗剩下的任何东西。我想确保我的戒指消失并且PortAudio冲洗了。回调是唯一知道戒指消退的地方,所以返回paComplete感觉合适。但后来我需要一些方法来知道释放我的戒指是可以的。

c audio portaudio
1个回答
0
投票

对此的答案是,它高度依赖于主机,即使对于一个主机,行为也可能随时间而变化。我继续阅读实现,我在这里发现了一些有用的信息。

Pa_StopStream将只调用主机系统的Stop()行为。我没有阅读所有的实现,但可能大多数都有某种阻止Stop()。这意味着阻止停止而不实际请求阻止行为是不太可能的。

PaStreamFinishedCallback也只是主机自己的流停止回调的瘦包装。例如,在OSX Core Audio中,这是Listener上的kAudioOutputUnitProperty_IsRunning。这完全取决于主机如何以及何时调用它。我认为这里的智能游戏应该尽可能谨慎 - 假设在这个回调中没有阻塞操作是安全的。

所以,如果你和我一样的情况,一个线程将PCM送入环形缓冲区,而PaStreamCallback从那个环读取,那么你可能想要

  • 订阅PaStreamFinishedCallback
  • 生产者线程关闭环形缓冲区,让PaStreamCallback排出它
  • 当戒指被排空时,从paComplete返回PaStreamCallback
  • 在我的情况下使用PaStreamFinishedCallback发信号通知pthread_cond_signal完成工作的生产者线程
  • 生产者线程通过解除分配唤醒并清理

甚至从音频线程发出信号(和锁定互斥锁)可能是最好的避免,但很难想象还有另一种选择。对于PCM环缓冲器的常规读数,PaStreamCallback可能在放弃之前旋转一些有限的次数。对于完成信号,生产者线程应该锁定然后立即等待,以便尽可能少地保持锁定。

© www.soinside.com 2019 - 2024. All rights reserved.