2016-11-14 196 views

回答

1

API有助于确定要捕获的数据缓冲区的大小,以便API客户端不需要猜测或分配具有多余的缓冲区等。当没有数据要捕获时,API将返回零(不是一个单一的框架)。在/正在进行音频捕捉会话时,可能会发生这种情况,因为过早调用API,并且由于仍然可以生成新数据,因此基本上希望调用者再次尝试。

在某些情况下,零回报可能表示流的结束。具体而言,如果您从回送设备捕获并且没有可以生成用于回送传送的数据的活动回放会话,则捕获API可能在新的回放会话出现之前不会继续传送数据。

示例代码循环检查零数据包大小,并调用Sleep。这样,循环期望至少一些数据在休眠时间期间产生,并且在连续生成音频数据的正常条件下,在外部循环内每第一次呼叫都不返回零长度。内部循环尝试尽可能多地读取非空缓冲区,直到零指示已准备好交付的所有数据已经​​返回给客户端。

外环继续运行,直到水槽通过bDone变量通过捕获结束事件。这里有一个问题,即内部循环可能会滚动而不会破坏外部循环 - 根据示例代码 - 捕获未正确停止。该示例假定接收器处理数据的速度足够快,以便内部循环可以处理所有当前可用的数据并爆发以致达到Sleep调用。也就是说,WASAPI调用都是非阻塞的,并且假设这些循环运行得非常快,这个想法是音频数据处理速度比捕获的速度快,并且循环花费大部分线程时间在Sleep调用中。也许不是初学者最好的示例代码。你可以通过在内部循环中检查bDone来改善它,以使它更可靠。

+0

感谢罗马为您解释。现在对我来说很清楚。但在示例代码中,“录制停止”场景还有一个困惑。有2个循环(外循环,检查是否停止,内循环检查数据包大小)。如果pMySink将'bDone'返回为true并且数据包仍然到达,那么即使pMySink发信号停止,录制仍将继续。另一方面,如果我们在内部循环中检查bDone,那么如果数据流中还有数据需要读取,那么就有丢失数据包的可能性。 – Nitin

+0

我在上面添加了。 “bDone”被假定为“捕获结束”信号,意味着接收器不需要新数据。显然可以有一般的新数据,尤其是如果源是活的。该示例没有记住,您可能需要从bDone指定的位置继续捕获。 –

+0

谢谢,现在我明白了。其实我正在制作一个音频捕捉应用程序,用户可以按录制和停止按钮开始和停止录制respt。录制(WASAPI捕获)是在单独的非UI线程中完成的,用户界面将发出记录停止信号,所以我的意图是不捕获额外的内容,但也没有任何中断。你的解释清除了我的困惑,现在我将优化我的实施。 – Nitin

相关问题