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 获取和设置声源音量投射角度

因为投射角度中外角肯定要比内角大,为了保证这一点我们需要做些额外的判断处理:

  1. void MainWindow::on_coneAnglesInside_valueChanged(int value)
  2. {
  3. DWORD insideAngle, outsideAngle;
  4. if (m_wavPlayer.get3DSource()->GetConeAngles(&insideAngle, &outsideAngle) != DS_OK)
  5. throw std::exception("GetConeAngles error");
  6. if (static_cast<unsigned>(value) > outsideAngle)
  7. ui->coneAnglesOutside->setValue(value),
  8. outsideAngle = value;
  9. if (m_wavPlayer.get3DSource()->SetConeAngles(value, outsideAngle, DS3D_IMMEDIATE) != DS_OK)
  10. throw std::exception("SetConeAngles error");
  11. ui->coneAnglesInsideLabel->setText(QString("coneAnglesInside(%1)").arg(value));
  12. }

2.3 获取和设置声源朝向

这里也有一个特殊情况要处理:朝向的3个维度不能都为0,否则就是一个无效的方向:

  1. #define SET_ONE_VECTOR_WITH_ZERO_CHECK_OF_SOURCE(getFunc, setFunc, sliderName, valueX, valueY, valueZ) \
  2. D3DVECTOR vector; \
  3. if (m_wavPlayer.get3DSource()->getFunc(&vector) != DS_OK) \
  4. throw std::exception(#getFunc " error"); \
  5. \
  6. if (!(valueX == 0.0 && valueY == 0.0 && valueZ == 0.0)) \
  7. if (m_wavPlayer.get3DSource()->setFunc(valueX, valueY, valueZ, DS3D_IMMEDIATE) != DS_OK) \
  8. throw std::exception(#setFunc " error"); \
  9. \
  10. ui->sliderName##Label->setText(QString(#sliderName "(%1)").arg(value));
  11. void MainWindow::on_coneOrientationX_valueChanged(int value)
  12. {
  13. SET_ONE_VECTOR_WITH_ZERO_CHECK_OF_SOURCE(GetConeOrientation, SetConeOrientation, coneOrientationX,
  14. value, vector.y, vector.z);
  15. }

其他相关设置这里就不给出代码了,都比较简单,有需要的可以看官方文档

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. HTML标签的命名/CSS标准化命名大全

    在一个内容较多的HTML页面中,需要设计许多不同的框架,再为这些不同的框架及内容进行分类,给予相应的名称,从而使得网页结构更加清晰,也为工作提供了方便.许多新手朋友在设计一个HTML文件时,可能只会依 ...

  2. redux简明学习

    前面的话 这几天被redux折腾的够呛,看了很多视频,也看了很多资料.很多时候,感觉好像顿悟了,但实际上只是理解了其中的一个小概念而已.真正去做项目的时候,还是会卡壳.可能是学CSS和Javascri ...

  3. 为Android添加JNI支持

    起因 今天在进行Android原生开发时,需要通过JNI调用C++代码实现一些处理.以前没有做过类似的东西,在网上找了很久才解决问题,特记录下来以便以后翻阅. Eclipse无cygwin编译so的方 ...

  4. mysql sql_cache缓存使用

    有如下规则,如果数据表被更改,那么和这个数据表相关的全部Cache全部都会无效,并删除之.这里"数据表更改"包括: INSERT, UPDATE, DELETE, TRUNCATE ...

  5. 洛谷P1962 斐波那契数列【矩阵运算】

    洛谷P1962 斐波那契数列[矩阵运算] 题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) ( ...

  6. Redis Sentinel 高可用服务搭建

    阅读目录: 关于 Redis 的概念 关于 Redis Sentinel 的概念 搭建 Redis Server(master) 搭建 Redis Server(slave) 搭建 Redis Sen ...

  7. String类为什么是final的

    首先我们使用new创建一个String对象的时候比如: String str=new String("123"); 这句话里面创建了两个对象,第一个在系统中创建了一个"a ...

  8. 又是一个愚蠢的错误,皆因.xml而起

       论java中的.xml到底有多坑?! 感觉自己都快哭了,再一次被.xml给坑了一下,这次坑的太狠了,一下子导致自己浪费了昨天一下午,一晚上,今天一上午和半个下午呀,中间的过程真的是乏善可陈呀,各 ...

  9. Android Stdio 如何自定义生成APK的名称

    Android Stdio自动默认生成的app的名称都是app-release或者app-debug,生成完后还要手动更改apk的名称,很是麻烦. 自定义生成APK的名称的方法:在\app\build ...

  10. Redis 设置开机启动

    1. 将下列代码保存为文件redis, 置于 /etc/init.d 下面 ########################### # chkconfig: 2345 90 10 redis服务必须在 ...