我在 wp8 中使用 WASAPI。因为我Getbuffer
每次在共享模式下使用方法返回不同大小的缓冲区。我以 8000Hz/16 位捕获,有时Getbuffer
返回 80 个样本的缓冲区,有时返回 400 个样本。这是正常的行为吗?发送不同的 hnsBufferDuration 对IAudioClient::Initialize
缓冲区大小没有任何影响?
2 回答
如MSDN 上所述:
该
IAudioClient::Initialize
方法分配缓冲区。客户端在传递给 Initialize 方法的 hnsBufferDuration 参数值中指定缓冲区长度。[...]对于捕获客户端,缓冲区长度决定了音频引擎在单次处理过程中可以从端点缓冲区读取的最大捕获数据量。客户端应始终
GetBufferSize
在调用 Initialize 后调用以确定分配缓冲区的实际大小,这可能与请求的大小不同。
API 以对捕获层有意义的方式实现它,并以最小的 API 开销为目标。它不会无缘无故地在内部积累数据。如果您需要固定大小的缓冲区,您可以自由地将数据堆积在您管理的缓冲区上。
是的,这是正常行为。我不具体了解 Windows Phone,但至少在 Windows 桌面上,这是共享模式捕获应该工作的方式,所以我怀疑它在 wp8 上没有什么不同。在处理 WASAPI 捕获缓冲区时,您应该注意 3 件事。
缓冲区的总大小,在 IAudioClient::Initialize 中指定为 hnsBufferDuration。WASAPI 将创建一个请求大小或更大的缓冲区。调用 IAudioClient::GetBufferSize 以获取实际的总缓冲区大小。
周期性(也是 IAudioClient::Initialize 的一个参数)。此参数指定 WASAPI 处理缓冲区的频率,例如,您可以设置一个 30 ms 的缓冲区,WASAPI 每 3 ms 处理一次。周期性仅用于独占模式。
数据包大小,这就是你要处理的。发生的情况是内部 WASAPI 缓冲区的大小实际上并没有改变(这是由 GetBufferSize 报告的),它只是在不同大小的小部分中处理。
如果您想提前知道下一个块有多大,请调用 IAudioCaptureClient::GetNextPacketSize(仅适用于共享模式)。如果您只想预先分配自己的缓冲区,这样您就不必在每次调用 GetBuffer 时重新分配,您可以设置自己的缓冲区,其大小等于 IAudioClient::GetBufferSize。