DirectSound能帮我们做什么?DirectSound开发指南 天天观察
1DirectSound简介(Introduction to DirectSound)
曾经学习过Directshow的开发,对于Dsound一直没有仔细的莱学习,以前只是知道Dsound是做音频开发的,我一直以为它和Dshow的结构体系差不多,经过仔细学习后,发现,其实他们完全 两码事。
(资料图片)
闲话少说,下面我们看看DirectSound到底能帮我们做些什么。
1播放WAVE格式的音频文件或者资源。
2可以同时播放多个音频。
3Assign high-priority sounds to hardware-controlled buffers
4播放3D立体声音
5在声音中添加特技效果,比如回声,动态的改变特技的参数等
6将麦克风或者其他音频输入设备的声音录制成wave格式的文件
呵呵,DirectSound就能做这么多事情,读到这里,我都有点怀疑DirectSound是不是就是封装了mmio系列和wav系列的函数。因为这些底层的API也能够完成这些事情。
2DirectSound初体验(Getting Started with DirectSound)
在开始本节内容前,我会首先提醒一下,如果你想用Directsound开发,那么你首先要包含Dsound.h头文件,其实我可以实话告诉你,你仅仅包含dsound.h你的工程肯定调补通,其实下面的一些头文件也要包含,我第一次就搞了半天才搞好,
#include
#include
#include
#include
如果你还想使用Dsound的API的话,那么你就要在你的vc开发环境中添加Dsound..lib库,
如果你的程序还提示有很多的外部链接找不到,那么我建议你可以将下面的库都添加到你的工程中comctl32.lib dxerr9.lib winmm.lib dsound.lib dxguid.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib,这些是我从Dsound提供的例子中得到的,肯定够你用的,ok,开发环境配置好了。
下面我们简单的来学习一下如果通过Directsound的API播放声音,既然是breif overview,那么详细的内容你可以参考下面的一节内容,这里只是简单的介绍一下播放声音的步骤。
第一步,创建一个设备对象。
在你的代码中你可以通过调用DirectSoundCreat8函数来创建一个支持IDirectSound8接口的对象,这个对象通常代表缺省的播放设备。当然你可以枚举可用的设备,然后将设备的GUID传递给DirectSoundCreat8函数。
注意,Directsound虽然基于COM,但是你并不需要初始化com库,这些Directsound都帮你做好了,当然,如果你使用DMOs特技,你就要自己初始化com库了,切记。
第二步,创建一个辅助Buffer,也叫后备缓冲区
你可以通过IDirectSound8::CreateSoundBuffer来创建buffer对象,这个对象主要用来获取处理数据,这种buffer称作辅助缓冲区,以和主缓冲区区别开来,Direcsound通过把几个后备缓冲区的声音混合到主缓冲区中,然后输出到声音输出设备上,达到混音的效果。
第三步,获取PCM类型的数据
将WAV文件或者其他资源的数据读取到缓冲区中。
第四步,将数据读取到缓冲区
你可以通过IDirectSoundBuffer8::Lock.方法来准备一个辅助缓冲区来进行写操作,通常这个方法返回一个内存地址,见数据从你的私人buffer中复制到这个地址中,然后调用IDirectSoundBuffer8::Unlock.
第五步,播放缓冲区中的数据
你可以通过IDirectSoundBuffer8::Play方法来播放缓冲区中的音频数据,你可以通过IDirectSoundBuffer8::Stop来暂停播放数据,你可以反复的莱停止,播放,音频数据,如果你同时创建了几个buffer,那么你就可以同时来播放这些数据,这些声音会自动进行混音的。
呵呵,简单介绍到这里的,如果想深入了解,请继续参考下一部分。
3DirectSound实用开发技巧Using DirectSound
在进行这部分之前,我们首先学习一下Directsound中常用的几个对象,简单学习一下哦
对象数量作用主要接口
设备每个应用程序只有一个设备对象用来管理设备,创建辅助缓冲区IDirectSound8
辅助缓冲区每一个声音对应一个辅助缓冲区用来管理一个静态的或者动态的声音流,然后在主缓冲区中混音IDirectSoundBuffer8, IDirectSound3DBuffer8, IDirectSoundNotify8
主缓冲区一个应用程序只有一个主缓冲区将辅助缓冲区的数据进行混音,并且控制3D参数.IDirectSoundBuffer, IDirectSound3DListener8
特技没有,或者来辅助缓冲的声音数据进行处理Interface for the particular effect, such as IDirectSoundFXChorus8
首先,要创建一个设备对象,然后通过设备对象创建buffer对象。辅助缓冲区由应用程序创建和管理,DirectSound会自动地创建和管理主缓冲区,一般来说,应用程序即使没有获取这个对象的接口也可以播放音频数据,但是,如果应用程序要想得到IDirectSound3DListener8接口,就必须要自己创建一个主缓冲区。
我们可以将短小的声音文件全部读取到辅助缓冲区中,然后通过一个简单的命令来播放。如果声音文件很长,就必须采用数据流了。
3.1Dsound设备对象(DirectSound Devices)
本节主要讲述下面的几个内容
1如何枚举系统输出声音的设备
2创建设备对象
3设置声音设备的协作度
–
下面首先看看如何枚举系统中的声音输出设备
1如何枚举系统输出声音的设备
如果你的应用程序使用用户首选的输出设备来输出声音,那么你就没有必要来枚举所有的输出设备,如果你通过DirectSoundCreat8函数来创建一个设备对象的同时,就给这个对象指定了一个缺省的设备,当然如果遇到下面的一些情形,你就要来枚举设备对象
例如,你的应用程序并不支持所有的输出设备,或者你的应用程需要两个或者多个设备,或者你希望用户自己来选择输出设备。
枚举设备,你首先要定义一个回调函数,这个回调函数可以被系统中的每个设备来调用,你可以在各函数做任何事情,这个函数的命名也没有任何的限制,但是函数应该以DSEnumCallback为原型,如果枚举没有结束,这个回调函数就返回TRUE,如果枚举结束,例如你找到合适的设备,这个函数就要返回FALSE。
下面是回调函数的一个例子,这个函数将枚举的每一个设备都添加到一个combox中,将设备的GUID保存到一个item 中,这个函数的前三个参数由设备的驱动程序提供,第四个参数有DirectSoundEnumerate函数提供,这个参数可以是任意的32位值,这个例子里是combox的句柄,
BOOL CALLBACK DSEnumProc(LPGUID lpGUID,
LPCTSTR lpszDesc,
LPCTSTR lpszDrvName,
LPVOID lpContext )
{
HWND hCombo = (HWND)lpContext;
LPGUID lpTemp = NULL;
if (lpGUID != NULL) // NULL only for "Primary Sound Driver".
{
if ((lpTemp = (LPGUID)malloc(sizeof(GUID))) == NULL)
{
return(TRUE);
}
memcpy(lpTemp, lpGUID, sizeof(GUID));
}
ComboBox_AddString(hCombo, lpszDesc);
ComboBox_SetItemData(hCombo,
ComboBox_FindString(hCombo, 0, lpszDesc),
lpTemp );
free(lpTemp);
return(TRUE);
}
枚举设备通常都是在对话框初始化的时候才进行的,我们假设hCombo就是combox句柄,hDlg就对话框的句柄,看看我们怎么来枚举设备的吧
if (FAILED(DirectSoundEnumerate((LPDSENUMCALLBACK)DSEnumProc,
(VOID*)&hCombo)))
{
EndDialog(hDlg, TRUE);
return(TRUE);
}
在这个例子中,combox的句柄作为参数传递到DirectSoundEnumerate函数中,然后又被传递到回调函数中,这个参数你可以是你想传递的任意的32位值。
注:第一个被枚举的设备通常称为Primary sound driver,并且回调函数的lpGUID为NULL,这个设备就是用户通过控制面板设置的缺省的输出声音设备,
2创建设备对象
创建设备对象最简单的方法就是通过DirectSoundCreate8函数,这个函数的第一个参数指定了和这个对象邦定的设备的GUID,你可以通过枚举设备来获取这个设备的GUID,你可以传递一个下面的参数来指定一个缺省的设备
DSDEVID_DefaultPlayback 缺省的系统的声音输出设备,这个参数也可以为NULL
SDEVID_DefaultVoicePlayback,缺省的声音输出设备,通常指第二缺省设备,例如USB耳机麦克风
如果没有声音输出设备,这个函数就返回error,或者,在VXD驱动程序下,如果声音输出设备正被某个应用程序通过waveform格式的api函数所控制,该函数也返回error,
下面是创建对象的代码,及其简单
LPDIRECTSOUND8 lpds;
HRESULT hr = DirectSoundCreate8(NULL, &lpds, NULL));
如果你想通过表准的COM调用来创建设备对象,下面我就给出代码,你可以比较一下
HRESULT hr = CoInitializeEx(NULL, 0);
if (FAILED(hr))
{
ErrorHandler(hr); // Add error-handling here.
}
LPDIRECTSOUND8 lpds;
hr = CoCreateInstance(&CLSID_DirectSound8,
NULL,
CLSCTX_INPROC_SERVER,
IID_IDirectSound8,
(LPVOID*) &lpds);
if (FAILED(hr))
{
ErrorHandler(hr); // Add error-handling here.
}
hr = lpds->Initialize(NULL);
if (FAILED(hr))
{
ErrorHandler(hr); // Add error-handling here.
}
CoUninitialize();
3设置声音设备的协作度
因为Windows是一个多任务操作环境,在同一个时刻有可能多个应用程序共用同一个设备,通过协作水平,DirectX就可以保证这些应用程序在访问设备的时候不会冲突,每个Directsound应用程序都有一个协作度,用来确定来接近设备的程度,
当你创建完设备对象后,一定要调用IDirectSound8::SetCooperativeLevel来设置协作度,否则,你不会听到声音的,
HRESULT hr = lpDirectSound->SetCooperativeLevel(hwnd, DSSCL_PRIORITY);
if (FAILED(hr))
{
ErrorHandler(hr); // Add error-handling here.
}
Hwnd参数代表了应用程序的窗口。
DirectSound定义了三种水平,DSSCL_NORMAL, DSSCL_PRIORITY, and DSSCL_WRITEPRIMARY
在NORMAL水平的协作度下,应用程序不能设置主缓冲区的格式,也不能对主缓冲区进行写操作,所有在这个层次的应用程序使用的媒体格式都是22kHZ,立体声,采样精度8位,所以,设备可以在各个应用程序中任意的切换。
在Priority层次的协作度下,应用程序可以有优先权使用硬件资源,比如使用硬件进行混音,当然也可以设置主缓冲区的媒体格式,游戏程序应该采用这个层次的协作度,这个层次的协作度在允许应用程序控制采用频率和位深度的同时,也给应用程序很大的权力,这个层次的协作度允许其他应用程序的声音和游戏的音频同时被听到,不影响。
最高层次的协作度就是Write_primary,当采用这个层次的协作度来使用一个dsound设备时,在非WDM模式驱动下,你的应用程序可以直接操作主缓冲区,在这个模式下,应有程序必须直接的操作主缓冲区。如果你想直接把音频数据直接写入到主缓冲区,你就要将你的协作度模式设置为writeprimary,如果你的应用程序没有设置到这个层次,那么所有的对主缓冲区的IDirectSoundBuffer::Lock都会失败。
当你的应用程序的协作度设置为wirte_primary水平时,并且你的应用程序gains the foreground,那么其他应用程序的辅助缓冲区就会停止,并且标示为lost,当你的应用程序转到background,那么它的主缓冲区就会标示为lost,当它再次回到foreground的时候会恢复到原来的状态,如果你的设备没有出现在你的系统中,那么你就没法设置wirte primary协作度了,所以,在设置协作度之前,可以通过IDirectSound8::GetCaps方法来查询一下设备是否可用。
4设置声音设备(扬声器)
在windowos98或者2000系统中,用户可以通过控制面板来设置扬声器的属性,应用程序可以通过IDirectSound8::GetSpeakerConfig.函数来获取这些属性,我们不建议应用程序通过IDirectSound8::SetSpeakerConfig函授来设置扬声器的属性,因为这些设置的改动会影响到其他用户或者应用程序。
5查询输出设备的性能
你的应用程序可以通过Directsound来检查声音设备的性能,然而许多应用程序并不需要这么做,因为Directsound会自动地利用硬件提供的较好的性能,并不需要你手动地来选择。
但是,However, high-performance applications can use the information to scale their sound requirements to the available hardware. For example, an application might choose to play more sounds if hardware mixing is available than if it is not.
当你调用DirectSoundCreate8创建一个设备对象后,你的应用程序就可以通过IDirectSound8::GetCaps函数来获取设备的性能属性,下面的代码演示了这个过程
DSCAPS dscaps;
dscaps.dwSize = sizeof(DSCAPS);
HRESULT hr = lpDirectSound->GetCaps(&dscaps);
if (FAILED(hr))
{
ErrorHandler(hr); // Add error-handling here.
}
通过DSCAPS结构,该函数就给我返回硬件设备的一些性能,但是在调用这个函数之前一定要初始化这个结构的dwSize成员。
如果你的应用程序能够操作硬件设备,比如你的协作度是Write_primory级别的,那么你在硬件设备上分配内存的时候,就要调用IDirectSoudn8::GetCaps来查看一下硬件的资源是否满足你的要求。
标签: 应用程序
相关推荐:
最新新闻:
- 环球今热点:【全国计算机等级考试】2级公共基础120题之四(11)
- DirectSound能帮我们做什么?DirectSound开发指南 天天观察
- test.c测试游戏:测试三子棋的逻辑-最新资讯
- 每日信息:pp助手安装失败怎么办?PP助手修复方法
- 世界速读:5.0以下的主流图片加载框架有哪些?安卓加载图片四大框架
- 磁盘垃圾文件清理器是什么?python接收命令行参数的方式及步骤-今日热讯
- iOS13越狱教程:如何安装AppSync和afc2补丁?
- 当前资讯!在哪里看股指期货的行情?股指期货行情信息
- 热门看点:【激活码】180天诺顿NAVirus2012版本安装
- 操作系统中死锁的算法——银行家算法-环球播报
- 全球快消息!进销存软件哪家强?上百种进销存软件大比拼
- 每日简讯:乔尔演员想看《最后的生还者》第二季还原“乔尔之死”:最真实的版本
- 《漫漫长夜》将于4月16日离开XGP
- 荷兰弟新剧定档6月9日:在片中演精神病人|当前快讯
- 央视探访天马科技集团 | 出口内销两旺,鳗鱼产业迎来消费利好!
- N64Switch在线追加《宝可梦竞技场2》4月12日上线
- 英国实体周榜:春季游戏没人打得过《生化4重制》
- 佩蒂特:梅西被嘘简直是对足球的侮辱!
- 发行商Devolver收购《枪伞游侠》开发商doinksoft 天天热消息
- 英特尔宋继强:面向半导体“万亿时代”,以全栈创新推动算力发展_环球观焦点
- 惠普第9代游戏家族重磅发布,助力玩家 玩出内力 再来亿把|环球实时
- 出游踏青随手拍出美景 逛京东手机焕新季入手爆款新机更超值
- 快用苹果助手如何安装?快用苹果助手安装不了怎么办?
- XLUEOPS.exe是什么?XLUEOPS.exe删除的方法
- Cydia源是什么?Cydia软件卸载步骤
- dnf画面卡是怎么回事?DNF卡屏最快解决方法是什么?
- 聚焦:观察|2023年在未来五年中发挥什么样的重要作用
- MP3Resizer如何压缩MP3文件?MP3Resizer安装及使用教程
- 任务管理器打不开怎么办?任务管理器打不开解决方法
- 无线网络连接不可用怎么办?无线网络连接不可用的解决方法
- 环球精选!穷人靠变异!DC新片《蓝甲虫》预告:拉丁超英来袭
- 本地网速测试有哪些方法?本地网速测试方法
- 如何设置使用激活工具oem7F7?oem7F7使用激活方法介绍
- win10运行lol一直崩溃怎么办?win10运行lol一直崩溃解决方法
- 88e6060是什么芯片?88e6060特性和好处
- 视频如何转换为AMV格式?AMV转换精灵操作方法
- LOL图标怎么点亮?qq上的英雄联盟图标怎么点亮?
- desktop.ini是什么文件?desktop.ini可以删除吗?
- 怎么用win10制作iso镜像文件?win10制作iso镜像文件的步骤教程
- 为什么电脑看视频卡住不动?电脑看视频卡怎么办?
- win7出现黑屏代码0xc000025怎么办?黑屏代码0xc000025解决办法
- snapchat怎么注册?Snapchat账号注册方法步骤
- Svchost.exe是什么进程?svchost.exe错误的原因及解决教程
- 桌面文件夹无法删除怎么解决?桌面文件夹无法删除解决方法
- 沪深股通|海利得4月3日获外资卖出0.04%股份:天天信息
- 快看点丨《魔术士奥芬》圣域篇新艺图角色 4月12日开播
- 《海洋奇缘》真人电影公布 巨石强森主演
- 广西启动第32个全国税收宣传月暨2023年广西助企纾困活动
- 《街头霸王》将拍真人电影!网友:让成龙大哥来
- AMD宣布开发DDR5 MRDIMM内存:目标17600MB/s
- 环球热文:《卧底公民》已登陆PS4/5 Steam获特别好评
- Switch里养一只猫咪《电子猫咪宠物》4月发售 焦点要闻
- 全球动态:空气压缩机油箱爆炸的原因是什么?_送男朋友生日礼物送什么好便宜真诚
- 他54岁担任福建省委副书记,曾多次保护赖昌星,57岁被判刑13年
- 开发者:顽皮狗新作将是全新IP!知名演员参与配音:世界快报
- HP发布暗影精灵9系列游戏本:RTX 4080干到13999元 要闻速递
- 埃文斯谈回归漫威:我很喜欢美队 但现在有些不对劲
- 《DOTA2》柏林Major 4月26日开打 奖金50万美元-全球速递
- 《龙与地下城:侠盗荣耀》北美开画夺冠
- 通灵学院钥匙任务前置_通灵学院的骷髅钥匙和观察室钥匙怎么弄
- 帅丰电器赋能终端,助力集成灶门店实现财富共赢
- 帅丰电器荆州集成灶门店开业活动启动会圆满成功! 当前热点
- 天天百事通!帅丰电器集成灶+集成水槽新品齐上线 速来一睹丰华
- vivo X Flip真机曝光:外屏超大 当前快讯
- 苹果手表被曝令手腕烫伤 真相来了
- 环球观速讯丨CS2的影响力!CSGO三月开箱近4千万 消费超1亿美元
- 德信中国披露业绩补充公告 称开元信德同意公布去年度财报数据 今日热讯
- 真我GT Neo5 SE首销破纪录:1999起 只用1小时
- 天天快消息!女子坐飞机意外发现自己包机了 临时增设、不对外售票
- 不给手机号不能点餐!上海消保委暗访扫码点餐乱象
- CDPR宣布提供月经假:痛经员工可全额带薪按需休假
- 成为螃蟹!这款肉鸽射击游戏《Crab Champions》好评如潮:爽就完事了
- 环球今头条!微星泰坦GP68HX游戏本开启预售 预售价15999元
- 聚焦用户精细化运营场景 极客邦科技与火山引擎数智平台达成合作
- 天天微资讯!真我GT Neo5 SE发布:1999元 骁龙7+旗舰