Skip to main content
在本主题中,我们将通过 Microsoft Game Development Kit (GDK) 附带的一个示例,逐步介绍在 XBOX Series X 设备上使用硬件卷积混响的预期代码流程。

硬件连接与启动

必须通过 XDspConnectXDspConnectWithMaximumStreamLimit 建立与硬件加速单元的连接。调用者使用以下参数设置连接的要求:
  1. baseBuffer - 指向用户分配的一块内存,其大小足以容纳将传给硬件的输入、输出、包络缓冲区和/或块乘子缓冲区 (block multiplier buffers)。该内存应通过 XMemAlloc 分配,属性为:XALLOC_MEMTYPE_PHYSICAL_CACHEABLEXALLOC_PAGESIZE_64KBXALLOC_ALIGNMENT_64K。这些属性应通过 MAKE_XALLOC_ATTRIBUTES() 设置,示例见下文。该内存在 XDspDisconnect 调用成功之前不能释放。此缓冲区至少 64KB。
  2. baseBufferLength - baseBuffer 的长度(字节数)。此缓冲区至少 64KB,且不超过 500 MB。
  3. aggregateImpulseResponseInSeconds - 代表将通过 XDspActivateXDspProcessType::Convolution 同时激活的所有单独脉冲响应的总时长。如果此值为 0,则不能激活任何 XDspProcessType::Convolution 类型的流。
  4. handle - 指向 XDspClientHandle 的指针,用于接收本次调用返回的句柄。
如果调用成功,调用者即可通过 XDspCommand 参数使用 baseBuffer 向硬件传入输入数据并获取流的输出数据。传给 XDspCommand 的任何缓冲区都必须按 16 字节对齐。以下是一个可用于管理输入输出缓冲区的简单缓冲区管理器示例。
每个流的包络缓冲区应与输入/输出缓冲区类似,属于传给 XDspConnectXDspConnectWithMaximumStreamLimit 的 baseBuffer 的一部分。每个包络缓冲区的长度可按如下方式计算。
以下是分配内存并建立连接的第一步代码示例。请注意,如果可以处于活动状态的流数量少于 256,可以用 XDspConnectWithMaximumStreamLimit 代替 XDspConnect 以减少内部内存使用。
其中 XMemAllocAttributes 表示上述属性。下列代码将 aggregateImpulseResponse 设为 32 秒。

流的激活与停用

在与设备建立连接后,调用者应发送一个流激活命令以启用卷积、FFT 或 IFFT。调用者必须在 XDspActivationParameters 中指定 XDspProcessType、块帧数、声道数、以浮点数表示的脉冲响应长度以及指向频域脉冲响应数据的指针。只允许单声道或立体声流。对于 XDspProcessType::ForwardFourierTransformXDspProcessType::inverseFourierTransformXDspActivationParameters::impulseResponse 应为 nullptr,且 XDspActivationParameters::impulseResponseLengthInFloats = 0。XDspActivationOptions 应做相应设置。 以下是激活一个卷积流的代码。
XDspActivate 会返回一个 XDspStatus 缓冲区作为其参数之一。该 XDspStatus 缓冲区可用于查询硬件为该流处理的命令的状态。收到激活结果后,调用者即可开始提交用于卷积/FFT/IFFT 的数据。这应通过 XDspSubmitCommandXDspSubmitCommandWithEnvelope API 完成。每次调用时,调用者必须:
  1. 用恰好 blockFrameCount 帧数据填充输入缓冲区。
  2. 用合适的值以及按 16 字节对齐的输入/输出缓冲区填充 XDspCommand
  3. 调用 XDspSubmitCommand 将命令提交给硬件。该函数会返回一个命令序号,可用于跟踪已发送给硬件的命令数量。
  4. 若要应用包络,请在包络缓冲区中填入脉冲响应滤波器每个块的增益值,并调用 XDspSubmitCommandWithEnvelope;继续用同一个包络缓冲区调用,直到不再需要包络或需要更换包络。
  5. 当不再需要包络时,请以 nullptr 作为 envelopeBuffer 调用 XDspSubmitCommandXDspSubmitCommandWithEnvelope。请注意,envelopeBuffer 为 nullptr 的 XDspSubmitCommandWithEnvelope 等价于 XDspSubmitCommand
  6. 切换包络时,只有当硬件处理完使用当前 envelopeBuffer 的所有命令且结果已被领取后,才可将当前 envelopeBuffer 更新为下一个包络内容。如果尚未处理完,请使用另一个包络缓冲区。
下列代码片段展示了如何使用脉冲响应滤波器每个块的增益值来填充包络缓冲区。示例演示了如何仅使用脉冲响应滤波器的前半部分:前半部分块的增益值从 1.0f 开始线性递减,后半部分则用 0.0f 填充。对于立体声脉冲响应滤波器,左声道的完整滤波器之后紧跟着右声道的滤波器——立体声脉冲响应滤波器的包络缓冲区遵循同样的模式:整个左声道的增益值之后紧跟着整个右声道的增益值。有关包络缓冲区大小的计算方式,请参见 使用 XDSP API 的包络概述
下列代码片段展示了通过传入有效的 envelopeBuffer 调用 XDspSubmitCommandWithEnvelope 来应用包络。除了额外传入 envelopeBuffer 参数外,此片段与使用 XDspSubmitCommand 提交命令的示例相同。应重复此过程,直到不再需要包络;届时应改为调用 XDspSubmitCommand,或者以 nullptr 作为 envelopeBuffer 调用 XDspSubmitCommandWithEnvelope
之后,可按如下方式检查 XDspStatus,以获取已提交给硬件的命令的状态:
当流中的数据包处理完毕,或硬件在 XDspStatus 结果中返回错误时,应调用 XDspDeactivate
如果硬件尚未完成本流所有已提交命令的处理,XDspDeactivate 会返回 XDSP_E_PENDING_RESULTS

终止

XDspDeactivate 成功后,调用者必须调用 XDspDisconnect 断开与音频硬件加速单元的连接,以释放所有已分配的资源。如果并非所有流都已停用,XDspDisconnect 会返回 XDSP_E_NOT_ALL_HANDLES_DEACTIVATED 错误。

参考 API 文档

另请参阅

XDSP 概述 使用 XDSP API 的包络概述
最后修改于 2026年8月24日