
示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载导读本指南以 Windows-universal-samples 仓库中的 SpatialSound 示例 为蓝本系统讲解如何在 Universal Windows Platform (UWP) 应用中利用HRTFHead-Related Transfer Function头相关传递函数xAPO与XAudio2 API渲染具有真实空间感的音频。通过阅读本文你将掌握HRTF xAPO 在 XAudio2 音频图Audio Graph中的挂载方式、全向Omnidirectional、心形Cardioid两种辐射模式的区别与配置方法以及自然距离衰减与自定义距离衰减两种衰减模型的实现细节并能够直接基于示例的 C 源码cpp 目录构建、运行和二次开发。示例概览在 XAudio2 图中托管 HRTF xAPOSpatialSound 示例的核心目标是把HRTF xAPO嵌入 XAudio2 的音频处理管线从而让不同空间位置、不同辐射模式、不同距离衰减行为的声源都能以双耳Binaural方式渲染配合耳机即可获得 360° 环绕声场。示例共提供三种可切换的运行场景全部以 C/CX 实现并共享同一套 XAudio2 基础设施场景辐射模式距离衰减用户可调节参数Scenario1_OmnidirectionalSound.xaml.cpp全向Omnidirectional自然距离衰减轨道半径、轨道高度、环绕速度、环境Outdoors/IndoorsScenario2_CardioidSound.xaml.cpp心形Cardioid自然距离衰减声源位置、朝向Pitch/Yaw/Roll、心形指向系数 Scaling、心形阶数 OrderScenario3_CustomDecay.xaml.cpp全向自定义距离衰减声源位置x/y/z其中自然距离衰减natural distance decay由 HRTF xAPO 依据声源到听者始终位于原点{0,0,0}的实际距离模拟现实世界的声压衰减规律而自定义距离衰减则由应用在每个渲染帧主动下发增益Gain值完全掌控衰减曲线。架构基础三阶段 XAudio2 音频图无论是哪种场景示例都复用了同一个音频图搭建函数 SetupXAudio2。该函数完整展示了 HRTF xAPO 在 XAudio2 中的标准宿主方式整体管线如下Source Voice源语音提交音频数据 → Submix Voice子混音语音挂载 HRTF xAPO执行双耳渲染 → Mastering Voice主控语音48kHz 立体声输出1. 以 1024 采样量子创建 XAudio2 实例auto hr XAudio2Create(xAudio2Instance, XAUDIO2_1024_QUANTUM);XAUDIO2_1024_QUANTUM标志指定了处理帧大小为 1024 个采样这是 HRTF 处理的必要配置——HRTF APO 以 1024 采样为量子处理数据。2. 创建 48kHz 立体声主控语音hr xAudio2Instance-CreateMasteringVoice(masteringVoice, 2, 48000);代码注释明确指出HRTF APO 期望单声道 48kHz 输入并输出 48kHz 立体声。因此主控语音按 2 声道、48000 Hz 渲染采样率创建。主控语音随 XAudio2 实例销毁而自动释放。3. 创建源语音并提交音频数据hr xAudio2Instance-CreateSourceVoice(sourceVoiceInstance, format);源语音以format来自 AudioFileReader 通过 Media Foundation 读取出的WAVEFORMATEX创建用于提交音频数据和控制播放启停。4. 创建挂载 xAPO 的子混音语音XAUDIO2_EFFECT_DESCRIPTOR fxDesc{}; fxDesc.InitialState TRUE; fxDesc.OutputChannels 2; // 立体声输出 fxDesc.pEffect xApo; // HRTF xAPO 作为效果挂载 XAUDIO2_EFFECT_CHAIN fxChain{}; fxChain.EffectCount 1; fxChain.pEffectDescriptors fxDesc; XAUDIO2_VOICE_SENDS sends {}; XAUDIO2_SEND_DESCRIPTOR sendDesc {}; sendDesc.pOutputVoice masteringVoice; sends.SendCount 1; sends.pSends sendDesc; // HRTF APO 期望单声道 48kHz 输入故子混音语音按该格式创建 hr xAudio2Instance-CreateSubmixVoice(submixVoice, 1, 48000, 0, 0, sends, fxChain);关键点在于子混音语音被配置为1 声道、48000 Hz匹配 HRTF APO 的单声道输入要求同时通过效果链XAUDIO2_EFFECT_CHAIN挂载 HRTF xAPO并将输出发送XAUDIO2_VOICE_SENDS指向主控语音。5. 将源语音路由到子混音语音XAUDIO2_VOICE_SENDS sends {}; XAUDIO2_SEND_DESCRIPTOR sendDesc {}; sendDesc.pOutputVoice submixVoice; sends.SendCount 1; sends.pSends sendDesc; hr sourceVoiceInstance-SetOutputVoices(sends);至此完整管线Source Voice → Submix Voice (HRTF xAPO) → Mastering Voice打通。所有场景的Initialize均在成功创建 HRTF xAPO 后调用SetupXAudio2并以XAUDIO2_LOOP_INFINITE无限循环提交示例自带的 MonoSound.wav随后通过Start()/Stop()控制播放。场景一全向声源 自然距离衰减默认 APO 初始化OmnidirectionalSound.cpp 展示了最简初始化路径// 传入 nullptr 即使用默认初始化全向辐射 自然距离衰减 hr CreateHrtfApo(nullptr, xapo);CreateHrtfApo的第一个参数传nullptrHRTF APO 便以全向辐射 自然距离衰减的默认行为初始化。随后通过xapo.As(_hrtfParams)查询出IXAPOHrtfParameters接口即可在运行时动态设置声源位置、朝向、增益与环境。注意在不支持 HRTF 的平台上CreateHrtfApo会返回E_NOTIMPL场景代码在捕获到该错误后会提示改用 X3DAudio API见 Scenario1_OmnidirectionalSound.xaml.cpp。轨道环绕每帧更新声源位置示例以DispatcherTimer驱动约 30 FPS 的更新循环timespan.Duration 10000 / 30每次 Tick 调用OnUpdate(angularVelocity, height, radius)HRESULT OmnidirectionalSound::OnUpdate(float angularVelocity, float height, float radius) { auto tick GetTickCount64(); auto elapsedTime tick - _lastTick; _lastTick tick; _angle elapsedTime * angularVelocity; _angle _angle HRTF_2PI ? (_angle - HRTF_2PI) : _angle; auto position ComputePositionInOrbit(height, radius, _angle); return _hrtfParams-SetSourcePosition(position); }轨道位置按右手坐标系计算-z 轴为前方z 轴为后方坐标单位为米float x radius * sin(angle); float z -radius * cos(angle); return HrtfPosition{x, height, z};UI 参数与滑块范围对应的 XAML 界面 Scenario1_OmnidirectionalSound.xaml 提供三个滑块和一个环境下拉框控件取值范围/默认值作用RotationSpeedSliderMaximum20步进 0.5一圈环绕所需秒数代码换算为角速度HRTF_2PI / (seconds * 1000)RadiusSliderMaximum10默认Value1步进 0.1环绕轨道半径米HeightSliderMinimum-10~Maximum10步进 0.5声源相对听者头部的高度米负值在下方EnvironmentComboBox0 Outdoors1 Indoors切换声学环境详见下文环境小节在 Scenario1_OmnidirectionalSound.xaml.cpp 中滑块ValueChanged事件仅保存参数实际位置更新发生在计时器 Tick 中从而保证轨道运动连续平滑。场景二心形辐射声源 自然距离衰减心形辐射的物理含义与全向声源向所有方向均匀辐射不同心形Cardioid声源具有指向性声音主要朝一个主方向辐射形成心形类心脏形的指向性图样。示例默认以ConfigureApo(1.0f, 4.0f)初始化即完全定向scaling1 较宽的辐射瓣order4。CardioidSound.cpp 的注释解释了关键语义order阶数越高心形指向区域越窄指向区域之外的直达信号会按scaling缩放因子衰减例如scaling 1完全定向时指向区域外的直达信号被完全衰减此时只能听到环境反射声。通过 HrtfApoInit 配置指向性HrtfDirectivityCardioid cardioid; cardioid.directivity.type HrtfDirectivityType::Cardioid; cardioid.directivity.scaling scaling; cardioid.order order; HrtfApoInit apoInit; apoInit.directivity cardioid.directivity; apoInit.distanceDecay nullptr; // nullptr 表示自然距离衰减模拟真实世界 auto hr CreateHrtfApo(apoInit, xapo);HrtfApoInit是 APO 初始化结构体directivity字段指定辐射模式这里为HrtfDirectivityType::CardioiddistanceDecay字段指定衰减模型nullptr即自然衰减。每帧更新位置与朝向HRESULT CardioidSound::OnUpdate(float x, float y, float z, float pitch, float yaw, float roll) { auto position HrtfPosition{ x, y, z }; hr _hrtfParams-SetSourcePosition(position); if (SUCCEEDED(hr)) { auto sourceOrientation OrientationFromAngles(pitch, yaw, roll); hr _hrtfParams-SetSourceOrientation(sourceOrientation); } return hr; }朝向通过 OrientationFromAngles 转换先将 pitch/yaw/roll 取负适配右手坐标系再用 DirectXMath 的XMMatrixRotationRollPitchYawFromVector生成旋转矩阵最后展开为HrtfOrientation所需的 3×3 矩阵元素。UI 端Scenario2_CardioidSound.xaml.cpp以SourcePositionX/Y/Z、Yaw/Pitch/Roll滑块控制这些参数。指向性变更重建 APO 而非逐帧修改一个重要的工程细节心形指向性在 xAPO 实例初始化时确定无法逐帧修改。因此 Scenario2_CardioidSound.xaml.cpp 在用户拖动 Scaling/Order 滑块时执行如下流程_timer-Stop(); _cardioidSound.ConfigureApo(scaling, order); // 停止引擎 → 重建 APO → 重建音频图 _timer-Start();而ConfigureApo内部会先StopEngine()并释放旧的 XAudio2 实例与_hrtfParams再以新指向性参数重新CreateHrtfApo、重建SetupXAudio2音频图并重新提交音频缓冲CardioidSound.cpp。若当时处于播放状态UI 会在重建后再次调用Start()恢复播放。这正是辐射模式为实例级配置、位置/朝向/增益为帧级配置的典型实现范式。场景三全向声源 自定义距离衰减自定义衰减参数CustomDecay.cpp 演示了如何通过HrtfDistanceDecay结构体接管距离衰减HrtfDistanceDecay customDecay; customDecay.type HrtfDistanceDecayType::CustomDecay; // 自定义衰减每帧下发增益 customDecay.maxGain 0; // 最大增益 0dB customDecay.minGain -96.0f; // 最小增益 -96dB customDecay.unityGainDistance HRTF_DEFAULT_UNITY_GAIN_DISTANCE; // 默认 unity 增益距离 customDecay.cutoffDistance HRTF_DEFAULT_CUTOFF_DISTANCE; // 默认截止距离 HrtfApoInit init; init.directivity nullptr; // nullptr 全向辐射 init.distanceDecay customDecay;四个字段的含义与示例取值字段示例值说明typeCustomDecay声明使用自定义衰减增益将由应用每帧下发maxGain0dB声源可达的最大增益minGain-96.0fdB声源的最小增益-96dB 近似静音unityGainDistance默认常量在此距离内增益为 0dBunity gaincutoffDistance默认常量衰减截止距离超出后按 minGain 处理每帧计算并下发增益HRESULT CustomDecaySound::OnUpdate(float x, float y, float z) { auto position HrtfPosition{ x, y, z }; hr _hrtfParams-SetSourcePosition(position); if (SUCCEEDED(hr)) { // 计算听者原点与声源的欧氏距离 auto distance sqrt(x*x y*y z*z); // ≤6m按 -2dB/米 线性衰减6~9m固定 -12dB9m-96dB静音 auto gain distance 6.0f ? (0 - (2 * distance)) : (distance 6.0f distance 9.0f) ? -12.0f : -96.0f; hr _hrtfParams-SetSourceGain(gain); } return hr; }这段代码给出了一个完整的分段衰减策略声源距听者 6 米以内按每米 -2dB 线性衰减69 米区间固定为 -12dB超过 9 米直接衰减到 -96dB静音。开发者可完全替换这段增益计算逻辑实现任意自定义衰减曲线——这正是HrtfDistanceDecayType::CustomDecay的设计目的。运行时 API环境、位置、朝向与增益三个场景共享IXAPOHrtfParameters的运行时设置能力三个类的SetEnvironment实现一致见 OmnidirectionalSound.cpp、CardioidSound.cpp、CustomDecay.cppAPI参数说明SetEnvironment(HrtfEnvironment)Outdoors/Indoors配置距离线索用于计算早期与晚期混响可在任意时刻动态切换SetSourcePosition(HrtfPosition)右手坐标系单位米每帧更新声源相对听者头部的位置SetSourceOrientation(HrtfOrientation)3×3 旋转矩阵设置声源朝向心形等指向性声源必需SetSourceGain(float)分贝值自定义衰减模式下每帧下发增益环境HrtfEnvironment通过 UI 下拉框选择三个场景的 XAML 均含EnvironmentComboBox其SelectionChanged事件直接调用SetEnvironment注释明确环境可以在任意时刻更改说明该属性属于帧级可调参数与指向性实例级形成对照。构建与运行系统要求客户端Windows 10示例需 Visual Studio 构建、Windows 10 执行Phone 设备HRTF xAPO API 在 Phone 上存在但不可用nonfunctionalREADME 的Remark与System requirements均明确标注 Phone 不支持运行硬件空间音频需要佩戴耳机才能获得正确的双耳定位效果。构建步骤若通过 ZIP 下载整个示例集合务必解压完整归档而不仅是本示例所在文件夹以便获得共享依赖SharedContent目录启动 Visual Studio选择File → Open → Project/Solution进入解压后的Samples/SpatialSound/cpp目录双击解决方案文件 SpatialSound.sln按CtrlShiftB或选择Build → Build Solution完成编译。运行步骤仅部署选择Build → Deploy Solution部署并运行调试按F5或选择Debug → Start Debugging部署并运行不调试按CtrlF5或选择Debug → Start Without Debugging。运行后分别进入三个场景点击 Play场景一可听到声源围绕头部环形环绕场景二可通过调节 Scaling/Order 与朝向听到指向性变化场景三可通过拖动位置滑块验证自定义衰减曲线的听感效果。源码结构速览文件职责XAudio2Helpers.hSetupXAudio2搭建 Source → Submix(HRTF xAPO) → Mastering 音频图OmnidirectionalSound.h / .cpp全向声源默认 APO 初始化 轨道环绕位置计算CardioidSound.h / .cpp心形声源HrtfDirectivityCardioid配置 朝向矩阵转换CustomDecay.h / .cpp自定义衰减HrtfDistanceDecay 每帧SetSourceGainAudioFileReader.h基于 Media Foundation 的 WAV 读取辅助类SampleConfiguration.h场景注册FEATURE_NAME SpatialSoundSpatialSound.vcxproj / SpatialSound.sln工程与解决方案文件小结SpatialSound 示例为 UWP 应用接入空间音频提供了完整的参考实现以XAUDIO2_1024_QUANTUM 48kHz 单声道输入/立体声输出的 XAudio2 图为容器挂载 HRTF xAPO通过IXAPOHrtfParameters在每帧更新位置、朝向、增益与环境并以三种场景分别演示了全向 自然衰减心形 自然衰减全向 自定义衰减的配置范式。开发者在自己的应用中只需复用 SetupXAudio2 的音频图搭建逻辑再按场景需要填充HrtfApoInit指向性 衰减模型即可获得完整的双耳空间音频能力——前提是目标设备支持 HRTF API桌面 Windows 10 支持Phone 不支持且用户佩戴耳机聆听。赞分享示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载相关推荐UWP 中 Windows Runtime XML API 实战指南基于 Windows-universal-samples 的 XmlDocument 样例UWP 中 Windows Runtime XML API 实战指南基于 Windows universal samples 的 XmlDocument 样例示例工程UWP 多窗口实战基于 AppWindow 的 Windows-universal-samples 二次窗口开发指南UWP 多窗口实战基于 AppWindow 的 Windows universal samples 二次窗口开发指南 导读 本指南以 Windows univ示例工程UWP 中 ListView 与 GridView 的实战指南基于 Windows-universal-samples XamlListView 示例的源码解析UWP 中 ListView 与 GridView 的实战指南基于 Windows universal samples XamlListView 示例的源码解示例工程上一篇Cellpose 3D细胞分割中的条纹伪影问题分析与解决方案下一篇DeepStream-Yolo项目中RTMDet模型部署指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考