DirectSound---3D环境
DirectSound对于单声道的Wav文件(或者说对于单声道的PCM音频数据)提供了内置3D音效的模拟,你能够控制每一个声源和收听者的立体位置,对移动的物体应用多普勒效果等等。在单个应用程序中,可以有多个声源,但是只能有一个收听者。
1. 3D音效概念简介
- 3D坐标: 坐标采用左手笛卡尔坐标系,x轴向右延伸,y轴向上延伸,z轴向前延伸。
- 3D处理模式: DirectSound由三种3D环境处理模式:普通模式、禁用模式、头部相关模式。普通模式就是完整的3D模式,禁用模式不言而喻,头部相关模式是部分3D模式(因为该模式下所有的声源参数都是参考听者位置的,而不是参考原点)。
- 延迟生效: 因此每次应用3D配置,DirectSound都要进行大量的计算,可能会家中cpu的负担。因此,声源和听者都支持一种叫做延迟设置的方式,多个以延迟设置设置的参数需要调用提交函数才能应用到音频数据上,这样可以避免多次重复计算。

1.1 声源(Source)相关概念
- 最小距离: 在最小距离范围内,听到的声源音量大小保持不变;在最小距离范围外,听到的音量开始成比例衰减(例如最小距离是10米,则听者站在距离声源20米处听到的声音是原始声音的1/2)。
- 最大距离: 在最大距离外的听者,不管再怎么朝外移动,听到的音量都不会再减小。
- 朝向: 朝向用来指定声源投射的方向,具体见下一点。
- 音量投射角度: 3D环境下的音量有一个锥形的投射角度(当设置朝向时),分内角和外角:内角的声音是正常的音量,外角的音量通常是衰减的音量,在内角边界向外角边界过渡时音量逐级衰减。

- 移动速度: 移动速度在整个3D环境里主要是用来计算多普勒效应(Doppler Effect)的。
1.2 听者(Listener)相关概念
- 朝向: 听者的朝向角度由两个3维向量构成,实际上这个朝向是一个平面。两个三维向量都以听者头部中心为原点,一个向顶部延伸,一个向前延伸。

- 距离因子: 距离因子(Distance Factor)表示三维空间中的单位,与米成正比(例如距离因子为2,则一个三维点(1,0,0)表示现实中距离原点x轴2米)。
- 多普勒因子: 表示产生的多普勒效应是真实效应的几倍。
- 滚降因子: 表示音量随距离的衰减程度。0表示不衰减,1表示衰减成程度与现实环境相同,等等。
2. 3D示例程序
2.1 获取和设置声源最大最小距离
IDirectSound3DBuffer8::GetMaxDistance(D3DVALUE * pflMaxDistance);
IDirectSound3DBuffer8::GetMinDistance(D3DVALUE * pflMinDistance);
IDirectSound3DBuffer8::SetMaxDistance(D3DVALUE flMaxDistance, DWORD dwApply);
IDirectSound3DBuffer8::SetMinDistance(D3DVALUE flMinDistance, DWORD dwApply);
dwApply参数用来指定是立即生效还是延迟生效(需要调用CommitDeferredSettings函数)。
2.2 获取和设置声源音量投射角度
因为投射角度中外角肯定要比内角大,为了保证这一点我们需要做些额外的判断处理:
void MainWindow::on_coneAnglesInside_valueChanged(int value)
{
DWORD insideAngle, outsideAngle;
if (m_wavPlayer.get3DSource()->GetConeAngles(&insideAngle, &outsideAngle) != DS_OK)
throw std::exception("GetConeAngles error");
if (static_cast<unsigned>(value) > outsideAngle)
ui->coneAnglesOutside->setValue(value),
outsideAngle = value;
if (m_wavPlayer.get3DSource()->SetConeAngles(value, outsideAngle, DS3D_IMMEDIATE) != DS_OK)
throw std::exception("SetConeAngles error");
ui->coneAnglesInsideLabel->setText(QString("coneAnglesInside(%1)").arg(value));
}
2.3 获取和设置声源朝向
这里也有一个特殊情况要处理:朝向的3个维度不能都为0,否则就是一个无效的方向:
#define SET_ONE_VECTOR_WITH_ZERO_CHECK_OF_SOURCE(getFunc, setFunc, sliderName, valueX, valueY, valueZ) \
D3DVECTOR vector; \
if (m_wavPlayer.get3DSource()->getFunc(&vector) != DS_OK) \
throw std::exception(#getFunc " error"); \
\
if (!(valueX == 0.0 && valueY == 0.0 && valueZ == 0.0)) \
if (m_wavPlayer.get3DSource()->setFunc(valueX, valueY, valueZ, DS3D_IMMEDIATE) != DS_OK) \
throw std::exception(#setFunc " error"); \
\
ui->sliderName##Label->setText(QString(#sliderName "(%1)").arg(value));
void MainWindow::on_coneOrientationX_valueChanged(int value)
{
SET_ONE_VECTOR_WITH_ZERO_CHECK_OF_SOURCE(GetConeOrientation, SetConeOrientation, coneOrientationX,
value, vector.y, vector.z);
}
其他相关设置这里就不给出代码了,都比较简单,有需要的可以看官方文档。
3. 运行结果示意图
界面太大,我就分成3张图展示了:

完整代码见链接。
DirectSound---3D环境的更多相关文章
- CSS3 3D环境实现立体 魔方效果代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 第1部分: 游戏引擎介绍, 渲染和构造3D世界
原文作者:Jake Simpson译者: 向海Email:GameWorldChina@myway.com ---------------------------------------------- ...
- 三分钟学会用 js + css3 打造酷炫3D相册
之前发过该文,后来不知怎么回事不见了,现在重新发一下. 中秋主题的3D旋转相册 如图,这是通过Javascript和css3来实现的.整个案例只有不到80行代码,我希望通过这个案例,让正处于迷茫期的j ...
- 3D banner(CSS3+HTML5)
1.这是一篇 3Dbanner制作的简易流程,支持高版本的chrome和firefox浏览器,俩浏览器显示可能会有些差异 2.没有兼容性代码,因为仅仅只是熟悉流程,希望小伙伴们自己改善哈(>﹏& ...
- Material Design 概念,环境和基本属性
Material Design 概念,环境和基本属性 Material Design是随Android 5.0推出的一种设计概念, 涉及到了跨平台和设备的视觉,动态,交互设计等方面. 设计概念 M ...
- 【Unity3d游戏开发】Unity3D中的3D数学基础---向量
向量是2D.3D数学研究的标准工具,在3D游戏中向量是基础.因此掌握好向量的一些基本概念以及属性和常用运算方法就显得尤为重要.在本篇博客中,马三就来和大家一起回顾和学习一下Unity3D中那些常用的3 ...
- 3D建模与处理软件简介
[前言]自半年前笔者发表博客“什么是计算机图形学”以来,时常有人来向笔者询问3D模型的构建方法与工具.笔者的研究方向是以3D技术为主,具体包括3D建模,3D处理及3D打印三个方面,在3D建模与处理方面 ...
- CSS 3 3D转换
绘制3D环境 父元素设置了 preserve-3d 子元素就可以以父元素作为平面进行3d转换 transform-style: preserve-3d; 设置视点 :表示透视效果 值越小 透视效果 ...
- JAVA智能设备基于OpenGL的3D开发技术 之AABB碰撞检测算法论述
摘要:无论是PC机的3D还是智能设备应用上,碰撞检测始终是程序开发的难点,甚至可以用碰撞检测作为衡量3D引擎是否完善的标准.现有许多3D碰撞检测算法,其中AABB碰撞检测是一种卓有成效而又经典的检测算 ...
随机推荐
- 听说你开发.NET还在用VS,小哥哥给你推荐全平台的Rider
本文地址:http://www.cnblogs.com/likeli/p/8461010.html 前言 .NET平台的开发一直都只能使用Visual Studio来开发,自从dotnet core ...
- Math.abs(~2018),掌握规律!
Math.abs(~2018) 这要用到一些计算机的基础知识. Math.abs(x)指的是返回一个数的绝对值,而关键在"~2018",这是取反操作符,故取相反数得结果为-2018 ...
- jq自定义多选下拉列表框
多选选择国家插件 https://gitee.com/richard1015/dropDownList
- PHP入门学习精要
一.文件名 函数.配置文件等其他类库文件之外的一般是以.php为后缀(第三方引入的不做要求): ThinkPHP的模板文件默认是以.html 为后缀(可以通过配置修改): 二.其它命名 其它命名 规则 ...
- TensorFlow实战之实现AlexNet经典卷积神经网络
本文根据最近学习TensorFlow书籍网络文章的情况,特将一些学习心得做了总结,详情如下.如有不当之处,请各位大拿多多指点,在此谢过. 一.AlexNet模型及其基本原理阐述 1.关于AlexNet ...
- mysql有多条记录的单个字段想存为一个字段显示的方法
SELECT po.id,(SELECT GROUP_CONCAT(mr.member_type) as memberTypeList FROM prod_offer_member_rel mr WH ...
- CentOS7关闭/开启防火墙出现 Unit iptables.service failed to load
在vm中安装好tomcat,而且在liunx中使用nc命令可以返回成功,但是更换到window中访问不到tomcat的情况,是由于linux防火墙的问题造成的,传统的解决方式有2中 第一种解决方案: ...
- .addClass(),.removeClass(),.toggleClass()的区别
.addClass("className")方法是用来给指定元素增加类名,也就是说给指定的元素追加样式: 可以同时添加多个类名,空格符隔开 $("selector&quo ...
- hihoCoder Demo Day dp
题意:有一个机器人被困在一个的迷宫中,机器人的初始位置是,目的地是,并且它的移动方式很奇怪:只能一直向右,直到不能再向右才能把方向变成向下:只能一直向下,直到不能再向下才能把方向变成向右.迷宫中的每个 ...
- 动态添加数据源,根据用户登录切换数据库.编程式Spring事务.
根据用户注册,系统自动创建私有数据库,用户登录,动态添加数据源到Spring数据路由,Session超时删除数据源 好处:当数据量大的时候,类似水平切割效果,效率会高一些 坏处:数据源切换,Sprin ...