有关各种 WASAPI 交互的线程安全性的文档缺乏明确性。 对于 IAudioClock,它确实提到 IAudioClient::GetService() 和从中获取的接口的 Release() 必须从同一线程调用:https://learn.microsoft.com/en-us/windows/win32/ api/audioclient/nn-audioclient-iaudioclock
但是对于 IAudioClock::GetPosition() 来说,它根本没有说明是否只需要在同一个线程中调用,或者是否可以由任何线程调用?
我可以找到 'Note 的脚注 在 Windows 8 中,第一次使用 IAudioClient 访问音频设备应该是在 STA 线程上。来自 MTA 线程的调用可能会导致未定义的行为。' 此处: https://learn.microsoft.com/en-us/windows/win32/api/audioclient/nn-audioclient-iaudioclient
还有这个“当释放 IAudioRenderClient 接口实例时,客户端必须从与调用创建该对象的 IAudioClient::GetService 相同的线程中调用该接口的 Release 方法。” 此处: https://learn.microsoft.com/en-us/windows/win32/api/audioclient/nn-audioclient-iaudiorenderclient
除此之外,文档还说:“要释放 IAudioClient 对象并释放其所有关联资源,除了在 IAudioClient 接口本身上调用 Release 之外,客户端还必须释放对通过调用 GetService 创建的任何服务对象的所有引用。客户端必须从释放 IAudioClient 对象的同一线程中释放服务。':https://learn.microsoft.com/en-us/windows/win32/api/audioclient/nf-audioclient-iaudioclient-getservice
总的来说,这意味着 IAudioClient::GetService()、IAudioClock::Release() 和 IAudioRenderClient::Release() 都必须从同一线程调用。它还说:“你永远不应该从你的流线程中调用任何阻塞代码。如果你这样做,你就会出故障。 IAudioClock 方法正在阻塞。'
此处:https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/2f9ec79b-8cc3-4b75-a041-a2847613947e/synchronizing-audio-input-and-output- with-iaudioclockgetposition?forum=windowspro-audiodevelopment 我对在与通过 IAudioRenderClient 填充缓冲区的线程不同的线程中调用 IAudioClock::GetPosition() 的用例特别感兴趣。 由于 IAudioClock::GetPosition() 显然不够快,无法从填充 IAudioRenderClient 缓冲区的同一线程调用:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/2f9ec79b- 8cc3-4b75-a041-a2847613947e/同步音频输入和输出与iaudioclockgetposition?论坛=windowspro-audiodevelopment所以我试图弄清楚是否可以有效地将消息(向事件或 IOCP 发送信号)从处理 IAudioRenderClient::GetBuffer()/ReleaseBuffer() 的线程发布到另一个可以调用 IAudioClock::GetPosition() 的线程。 但我从文档中不知道这是否允许。
请注意,这与我的其他更普遍的问题相关:
音频渲染客户端位置的高效采样