代孕神父,冒牌天皇,苍蝇陷阱快播
DirectSound是DirectX组件之一,提供了对音频设备的捕获和播放能力,同时它也是唯一几个支持Xp系统的音频技术之一。 DirectSound主要有以下特点:
优点:
缺点:
这里我们说说设备操作这一块儿。
在DirectSound中,一个设备对象就代表一个音频设备,播放设备对象对应播放设备,输入设备对象对应输入设备。因为DirectSound使用COM协议,因此每个设备对象都用接口来表示。这里IDirectSound8这个接口就代表了一个输出设备对象,应用程序可以对同一个音频设备创建多个设备对象来进行音频输出操作。旧版本的DirectSound使用的是IDirectSound接口,相比前者少了一些功能。
HRESULT WINAPI DirectSoundEnumerateW(In LPDSENUMCALLBACKW pDSEnumCallback, In_opt LPVOID pContext);
typedef BOOL (CALLBACK *LPDSENUMCALLBACKW)(LPGUID, LPCWSTR, LPCWSTR, LPVOID);
我们通过DirectSoundEnumerateW这个函数来枚举,该函数需要传入一个回调函数(原型见上),当枚举到一个设备时该回调会被调用。如果我们想继续枚举,需要在这个回调用中返回TRUE来告诉系统,否则返回FALSE。另一个参数pContext
允许用户传入额外的参数,传入回调函数的最后一个实参就是这个pContext
。枚举时,DirectSound会将默认也认作一个单独的设备来对待,因此默认设备会被重复枚举一次。当设备被作为默认设备枚举时,它的GUID和设备描述字符串都为空,需要小心处理,这里我直接跳过了该次枚举:
if (DirectSoundEnumerateW(enumerateCallback, nullptr) != DS_OK) {
...
}
BOOL CALLBACK DirectSoundBasic::enumerateCallback(LPGUID guid,
LPCWSTR deviceDescription,
LPCWSTR deviceDriverModule,
LPVOID context)
{
Q_UNUSED(context);
// if primary device, skip it
if (guid == nullptr) return TRUE;
...
}
HRESULT WINAPI DirectSoundCreate8(In_opt LPCGUID pcGuidDevice, Outptr LPDIRECTSOUND8 *ppDS8, Pre_null LPUNKNOWN pUnkOuter);
调用DirectSoundCreate8函数,我们可以创建一个设备对象,通过传入一个枚举设备时获得的GUID,函数会返给我们一个IDirectSound8接口代表设备对象:
IDirectSound8* directSound8;
if (DirectSoundCreate8(guid, &directSound8, NULL) != DS_OK) {
std::wcout << L"[error] DirectSoundCreate8 call error!";
return TRUE; // if error, skip this device
}
HRESULT IDirectSound8::SetCooperativeLevel(HWND hwnd, DWORD dwLevel)
在使用设备对象创建缓冲区(用来捕获、播放音频)之前,我们需要设置设备对象的协作级别。这个协作级别相当于用户对设备进行操作的优先级,分为:
DSSCL_EXCLUSIVE: 互斥级别。对于DirectX8.0以前版本,仅播放当前应用的音频数据,其他应用的声音不会被播放;对于DirectX8.0级以后版本,同DSSCL_PRIORITY版本。
DSSCL_WRITEPRIMARY:写主缓冲区级别,应用可以直接写入主缓冲区,此时所有次缓冲区不会被播放(如果设备的驱动是DirectSound模拟出来的,则不能设置该级别)。
注意该函数需要传入一个窗口句柄,因为我们今天只介绍DirectSound的基本操作,我直接传入桌面窗口的句柄并设定位DSSCL_NORMAL优先级:
if (directSound8->SetCooperativeLevel(GetDesktopWindow(), DSSCL_NORMAL) != DS_OK) {
std::wcout << L"[error] SetCooperativeLevel call error!";
return TRUE;
}
HRESULT IDirectSound8::GetCaps(LPDSCAPS pDSCaps)
不同的音频播放设备具有不同的能力,DirectSound允许我们查询设备的能力:
我们传给GetCaps一个DSCAPS结构体地址,然后系统就帮我们填充相应的数据,调用GetCaps前需要将DSCAPS结构体的dwSize设置为DSCAPS的大小:
DSCAPS deviceCapability = { sizeof(deviceCapability) };
if (directSound8->GetCaps(&deviceCapability) != DS_OK) {
std::wcout << L"[error] GetCaps call error!";
return TRUE;
}
HRESULT IDirectSound8::GetSpeakerConfig(LPDWORD pdwSpeakerConfig)
HRESULT IDirectSound8::SetSpeakerConfig(LPDWORD pdwSpeakerConfig)
播放器配置只能是以下之一:
虽然MSDN文档没有写清楚,但是通过查以上宏定义我们发现它们是按大小顺序定义的,因此不可能通过OR|
来包含多种可能,例子中如果调用出错直接返回TRUE表示我们继续枚举设备并继续查询那些设备能力:
DWORD deviceSpeakerConfiguration;
if (directSound8->GetSpeakerConfig(&deviceSpeakerConfiguration) != DS_OK) {
std::wcout << L"[error] GetSpeakerConfig call error!";
return TRUE;
}
这次我们用GUI界面来显示实例运行的结果(出于方便考虑,以后我会用控制台来显示示例),为防止用户误操作更改显示的数据我将大部分控件都disable了:
完整代码见链接。
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
新补丁让Windows 10出现死机、卡顿等 微软坐不住称正解决
Ubuntu 20.04 LTS进驻Windows子系统:只能用3年
ThinkPad正式加入:预装Linux发行版而非Win10的PC越来越多了
最新版Android 11推送!谷歌Pixel 5被曝光:支持反向充电
高度致敬Windows!开源优麒麟20.04 LTS发布:支持5年
电脑小知识:Windows 10是用什么语言写的?到底有多少行代码?
Win10 5月更新准正式版:微软引入大量新功能 系统响应速度快
Windows 10新预览版19613推送:修复任务栏图标显示异常BUG
Windows AD 报错解决:UAC File Virtualization服务启动失败 此驱动程序被阻止加载
网友评论