PaStreamFinishedCallback

PaStreamFinishedCallback

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

或者,是否有类似Pa_StopStream的函数将阻塞,直到回调返回paComplete / paAbort,但不会引起停止?实际上这对我来说是理想的选择,因为我有一个线程适合我清理。我知道我可以通过向线程发出回调信号来完成此操作,然后线程可以调用Pa_StopStream,但感觉很费力。

编辑:为了给我更多的使用环境,我有一个环形缓冲区,其中装有一些PCM,并使用pthread condvar发出信号,告知缓冲区中何时有可用空间。一个线程写入该环,然后PaStreamCallback从另一端读取。完成后,编写器将在环上设置一个关闭标志,然后回调将耗尽所有剩余内容。我想确保我的铃声响了,并且PortAudio刷新了。回调是知道环何时耗尽的唯一位置,因此返回paComplete感觉合适。但是然后我需要某种方式来知道可以取消分配我的铃声。

最佳答案

对此的答案是,它高度依赖于主机,并且即使对于一台主机,其行为也可能随时间变化。我继续阅读了实现,然后在这里发现了一些有用的信息。
Pa_StopStream将仅调用主机系统的类似于Stop()的行为。我没有阅读所有实现,但大概大多数实现都有某种阻塞Stop()。这意味着在没有实际要求 parking 的情况下阻止 parking 是不太可能得到支持的。
PaStreamFinishedCallback只是主机自己的流停止回调上的精简包装。例如,在OSX Core Audio中,这是Listener上的kAudioOutputUnitProperty_IsRunning。调用方式和调用时间完全取决于主机。我认为这里的技巧应该尽可能谨慎-假设在此回调中没有阻塞操作是安全的。

因此,如果您和我一样,一个线程将PCM送入环形缓冲区,并且PaStreamCallback从该环形读取,那么您可能想要

  • 订阅PaStreamFinishedCallback
  • 生产者线程关闭环形缓冲区,并让PaStreamCallback耗尽它
  • 环耗尽时,从paComplete返回PaStreamCallback
  • 通知生产者线程,从PaStreamFinishedCallback完成工作,在本例中,使用pthread_cond_signal
  • 生产者线程通过唤醒分配
  • 来唤醒并清除

    甚至最好避免从音频线程发出信号(并锁定互斥体),但是很难想象还有其他选择。为了从PCM环形缓冲区进行常规读取,在放弃之前,PaStreamCallback可能应该旋转一定的次数。对于完成信号,生产者线程应该锁定,然后立即等待,以便它尽可能少地持有该锁定。

    关于c - PortAudio的PaStreamFinishedCallback上的安全操作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48014791/

    10-12 21:41