DirectSound对于单声道的Wav文件(或者说对于单声道的PCM音频数据)提供了内置3D音效的模拟,你能够控制每一个声源和收听者的立体位置,对移动的物体应用多普勒效果等等。在单个应用程序中,可以有多个声源,但是只能有一个收听者。

1. 3D音效概念简介

  1. 3D坐标: 坐标采用左手笛卡尔坐标系,x轴向右延伸,y轴向上延伸,z轴向前延伸。
  2. 3D处理模式: DirectSound由三种3D环境处理模式:普通模式禁用模式头部相关模式。普通模式就是完整的3D模式,禁用模式不言而喻,头部相关模式是部分3D模式(因为该模式下所有的声源参数都是参考听者位置的,而不是参考原点)。
  3. 延迟生效: 因此每次应用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环境的更多相关文章

  1. CSS3 3D环境实现立体 魔方效果代码

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 第1部分: 游戏引擎介绍, 渲染和构造3D世界

    原文作者:Jake Simpson译者: 向海Email:GameWorldChina@myway.com ---------------------------------------------- ...

  3. 三分钟学会用 js + css3 打造酷炫3D相册

    之前发过该文,后来不知怎么回事不见了,现在重新发一下. 中秋主题的3D旋转相册 如图,这是通过Javascript和css3来实现的.整个案例只有不到80行代码,我希望通过这个案例,让正处于迷茫期的j ...

  4. 3D banner(CSS3+HTML5)

    1.这是一篇 3Dbanner制作的简易流程,支持高版本的chrome和firefox浏览器,俩浏览器显示可能会有些差异 2.没有兼容性代码,因为仅仅只是熟悉流程,希望小伙伴们自己改善哈(>﹏& ...

  5. Material Design 概念,环境和基本属性

    Material Design 概念,环境和基本属性 Material Design是随Android 5.0推出的一种设计概念, 涉及到了跨平台和设备的视觉,动态,交互设计等方面.   设计概念 M ...

  6. 【Unity3d游戏开发】Unity3D中的3D数学基础---向量

    向量是2D.3D数学研究的标准工具,在3D游戏中向量是基础.因此掌握好向量的一些基本概念以及属性和常用运算方法就显得尤为重要.在本篇博客中,马三就来和大家一起回顾和学习一下Unity3D中那些常用的3 ...

  7. 3D建模与处理软件简介

    [前言]自半年前笔者发表博客“什么是计算机图形学”以来,时常有人来向笔者询问3D模型的构建方法与工具.笔者的研究方向是以3D技术为主,具体包括3D建模,3D处理及3D打印三个方面,在3D建模与处理方面 ...

  8. CSS 3 3D转换

    绘制3D环境 父元素设置了 preserve-3d  子元素就可以以父元素作为平面进行3d转换 transform-style: preserve-3d; 设置视点 :表示透视效果  值越小 透视效果 ...

  9. JAVA智能设备基于OpenGL的3D开发技术 之AABB碰撞检测算法论述

    摘要:无论是PC机的3D还是智能设备应用上,碰撞检测始终是程序开发的难点,甚至可以用碰撞检测作为衡量3D引擎是否完善的标准.现有许多3D碰撞检测算法,其中AABB碰撞检测是一种卓有成效而又经典的检测算 ...

随机推荐

  1. 使用WinInet实现HTTP站点访问

    废话不多说了,直接上代码 HTTP的GET方式代码 void sendGetRequest(LPCTSTR lpszURL) { LPCTSTR lpszAgent = _T("Winine ...

  2. git取消文件跟踪

    在使用git的时候,有些文件是不需要上传的,所以就可以修改   .gitignore 例如: 如果是对所有文件都取消跟踪的话,就是 git rm -r -cached .  //不删除本地文件 git ...

  3. DML、DDL、DCL的区别

    DML(data manipulation language): 它们是SELECT.UPDATE.INSERT.DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言DDL( ...

  4. DB2日常维护——REORG TABLE命令优化数据库性能(转)

    [转]DB2日常维护——REORG TABLE命令优化数据库性能 一个完整的日常维护规范可以帮助 DBA 理顺每天需要的操作,以便更好的监控和维护数据库,保证数据库的正常.安全.高效运行,防止一些错误 ...

  5. .net core 2.0学习笔记(二):部署到Windows和Liunx系统

    .Net Core最大的亮点就是跨平台了,下面介绍下在Windows下和Liunx下的部署. 首先发布项目文件,点击网站项目右键 发布: 从下图发布的文件图片可以看出,不像以前bin目录下有很多dll ...

  6. Yii2按需加载图片怎么做?

    按需加载图片应该用 jQuery LazyLoad 图片延迟加载按需加载文件夹应该用 Yii::import

  7. Centos6增加新用户并赋予权限

    第一步:创建用户并设置密码 useradd testuser // 增加用户名为'testuser'的用户 passwd testpasswd //设定密码为'testpasswd' 第二步:用户授权 ...

  8. iOS程序闪退的原因以及处理办法

    iOS程序闪退是一种比较常见的现象.闪退的情况很多,造成程序闪退的原因也很多. ================================启动时闪退======================= ...

  9. opencv 离线文档下载地址在哪里?

    OpenCV 官方离线文档下载地址:http://docs.opencv.org/ 如何生成离线文档? http://docs.opencv.org/master/d4/db1/tutorial_do ...

  10. window下如何使用Git上传代码到github远程服务器上(转)

    注册账户以及创建仓库 首先你得有一个github账号,没有自行注册,登录成功后应该是这样 在页面上方用户菜单上选择 "+"->New repository 创建一个新的仓库 ...