IAudioCaptureClient::GetBuffer 方法 (audioclient.h)

检索指向捕获终结点缓冲区中下一个可用数据包的指针。

语法

HRESULT GetBuffer(
  [out] BYTE   **ppData,
  [out] UINT32 *pNumFramesToRead,
  [out] DWORD  *pdwFlags,
  [out] UINT64 *pu64DevicePosition,
  [out] UINT64 *pu64QPCPosition
);

参数

[out] ppData

指向指针变量的指针,方法在该变量中写入可供客户端读取的下一个数据包的起始地址。

[out] pNumFramesToRead

指向 UINT32 变量的指针,该方法将帧计数 (数据包) 中可用的音频帧数写入其中。 客户端应读取整个数据包,或者不读取任何数据包。

[out] pdwFlags

指向 DWORD 变量的指针,方法将缓冲区状态标志写入其中。 方法写入以下一个或多个 _AUDCLNT_BUFFERFLAGS 枚举值的 0 或按位 OR 组合:

AUDCLNT_BUFFERFLAGS_SILENT

AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY

AUDCLNT_BUFFERFLAGS_TIMESTAMP_ERROR

注意 Windows Vista 不支持 AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY 标志。

在 Windows 7 及更高版本的操作系统中,此标志可用于故障检测。 若要启动捕获流,客户端应用程序必须调用 IAudioClient::Start ,然后循环中调用 GetBuffer 以读取数据包,直到读取终结点缓冲区中的所有可用数据包。 GetBuffer 设置 AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY 标志以指示 ppData 指向的缓冲区中的故障。

 

[out] pu64DevicePosition

指向 UINT64 变量的指针,该方法将数据包中第一个音频帧的设备位置写入其中。 设备位置表示为从流开始的音频帧数。 如果客户端不需要设备位置,此参数可以为 NULL 。 有关详细信息,请参阅“备注”。

[out] pu64QPCPosition

指向 UINT64 变量的指针,当音频终结点设备记录数据包中第一个音频帧的设备位置时,该方法会将性能计数器的值写入其中。 方法将计数器值转换为 100 纳秒单位,然后再将其写入 *pu64QPCPosition。 如果客户端不需要性能计数器值,此参数可以为 NULL 。 有关详细信息,请参阅“备注”。

返回值

可能的返回代码包括但不限于下表中显示的值。

返回代码 说明
S_OK
调用成功, 并且 *pNumFramesToRead 为非零值,指示数据包已准备好读取。
AUDCLNT_S_BUFFER_EMPTY
调用成功, 并且 *pNumFramesToRead 为 0,表示没有可供读取的捕获数据。
AUDCLNT_E_BUFFER_ERROR
Windows 7 及更高版本GetBuffer 无法检索数据缓冲区,并且 *ppData 指向 NULL。 有关详细信息,请参阅“备注”。
AUDCLNT_E_OUT_OF_ORDER
以前的 IAudioCaptureClient::GetBuffer 调用仍然有效。
AUDCLNT_E_DEVICE_INVALIDATED
音频终结点设备已拔出,或者音频硬件或关联的硬件资源已重新配置、禁用、删除或以其他方式不可用。
AUDCLNT_E_BUFFER_OPERATION_PENDING
无法访问缓冲区,因为正在进行流重置。
AUDCLNT_E_SERVICE_NOT_RUNNING
Windows 音频服务未运行。
E_POINTER
参数 ppData、pNumFramesToRead 或 pdwFlags 为 NULL

注解

此方法从捕获终结点缓冲区检索下一个数据包。 在特定时间,缓冲区可能包含零个、一个或多个已准备好读取的数据包。 通常,从捕获终结点缓冲区读取数据的缓冲区处理线程在每次执行线程时读取所有可用的数据包。

在处理音频捕获流期间,客户端应用程序交替调用 GetBufferIAudioCaptureClient::ReleaseBuffer 方法。 每次 调用 GetBuffer 时,客户端只能读取一个数据包。 每次 调用 GetBuffer 后,客户端必须调用 ReleaseBuffer 来释放数据包,然后客户端才能再次调用 GetBuffer 以获取下一个数据包。

不允许对 GetBufferReleaseBuffer 进行两次或多次连续调用,并且将失败并AUDCLNT_E_OUT_OF_ORDER错误代码。 为了确保调用顺序正确, GetBuffer 调用及其相应的 ReleaseBuffer 调用必须在同一线程中发生。

在每个 GetBuffer 调用期间,调用方必须获取整个数据包,或者不获取任何数据包。 读取数据包之前,调用方可以通过 pNumFramesToRead 参数) 检查数据包大小 (,以确保其有足够的空间来存储整个数据包。

在每次 ReleaseBuffer 调用期间,调用方报告从缓冲区读取的音频帧数。 此数字必须为 (非零) 数据包大小或 0。 如果号码为 0,则下一个 GetBuffer 调用将为调用方提供与上一个 GetBuffer 调用相同的数据包。

每次 调用 GetBuffer 后,数据包中的数据将保持有效,直到下一个 ReleaseBuffer 调用释放缓冲区。

在成功获取除 0 以外的任何大小的数据包的 GetBuffer 调用后,客户端必须调用 ReleaseBuffer。 客户端可以选择调用或不调用 ReleaseBuffer 来释放大小为 0 的数据包。

方法通过 pu64DevicePositionpu64QPCPosition 输出参数输出设备位置和性能计数器。 这些值为数据包中的第一个音频帧提供时间戳。 通过 pdwFlags 输出参数, 方法指示报告的设备位置是否有效。

方法写入 *pu64DevicePosition 的设备位置是音频帧的流相对位置,该音频帧当前正在通过扬声器 (为呈现流) 播放,或通过麦克风 (录制) 捕获流。 位置表示为从流开头开始的帧数。 音频流中帧的大小由 WAVEFORMATEX (或 WAVEFORMATEXTENSIBLE) 结构的 nBlockAlign 成员指定,该结构指定该流格式。 音频帧的大小(以字节为单位)等于流中的通道数乘以每个通道的样本大小。 例如,对于包含 16 位样本的立体声 (2 通道) 流,帧大小为 4 个字节。

GetBuffer 写入 *pu64QPCPosition 的性能计数器值不是从 QueryPerformanceCounter 函数获取的原始计数器值。 如果 t 是原始计数器值,并且 f 是从 QueryPerformanceFrequency 函数获取的频率, 则 GetBuffer 将按如下所示计算性能计数器值:

*pu64QPCPosition = 10,000,000t/F

结果以 100 纳秒为单位表示。 有关 QueryPerformanceCounterQueryPerformanceFrequency 的详细信息,请参阅 Windows SDK 文档。

如果当前没有可用的新数据包,该方法将 *pNumFramesToRead = 0,并返回状态代码AUDCLNT_S_BUFFER_EMPTY。 在这种情况下, 方法不会写入 ppDatapu64DevicePositionpu64QPCPosition 参数指向的变量。

客户端应避免获取数据包的 GetBuffer 调用与释放数据包的 ReleaseBuffer 调用之间的过度延迟。 音频引擎的实现假定 GetBuffer 调用和相应的 ReleaseBuffer 调用发生在同一缓冲区处理周期内。 将数据包释放延迟超过一段时间的客户端可能会丢失示例数据。

在 Windows 7 及更高版本中, GetBuffer 可以为在独占模式下使用终结点缓冲区的音频客户端返回 AUDCLNT_E_BUFFER_ERROR 错误代码。 此错误表示未检索数据缓冲区,因为数据包不可用 (*ppData 收到 NULL) 。

如果 GetBuffer 返回 AUDCLNT_E_BUFFER_ERROR,则使用音频样本的线程必须等待下一个处理阶段。 客户端可能会受益于保留失败的 GetBuffer 调用计数。 如果 GetBuffer 重复返回此错误,则客户端可以在关闭当前客户端后启动新的处理循环,方法是调用 IAudioClient::StopIAudioClient::Reset 并释放音频客户端。

示例

有关调用 GetBuffer 方法的代码示例,请参阅捕获Stream

要求

要求
最低受支持的客户端 Windows Vista [桌面应用 | UWP 应用]
最低受支持的服务器 Windows Server 2008 [桌面应用 | UWP 应用]
目标平台 Windows
标头 audioclient.h

另请参阅

IAudioCaptureClient 接口

IAudioCaptureClient::ReleaseBuffer

IAudioClient::GetMixFormat

IAudioClock::GetPosition