一、获取设备音量

不同系统获取音量的方法是有差别的,比如vista和win7获取音量的方式就是不同的,因此,我们应该首先获取系统的信息,然后根据系统信息,用其对应的方法获取音量。

1、OSVERSIONINFO

系统信息结构体

以下结构体均用于检索或设置系统信息。

ANIMATIONINFO
HW_PROFILE_INFO
MINIMIZEDMETRICS
NONCLIENTMETRICS
OSVERSIONINFO
SYSTEM_INFO 

使用说明
       在OSVERSIONINFO数据结构中包含操作系统版本信息。这些信息包括主要和次要版本号,一个内部版本号,一个平台标识符,以及操作系统的说明性文本。GetVersionEx函数将使用这个结构体。
 
结构体原型:

typedef struct _OSVERSIONINFO
{DWORD dwOSVersionInfoSize;DWORD dwMajorVersion;DWORD dwMinorVersion;DWORD dwBuildNumber;DWORD dwPlatformId;TCHAR szCSDVersion[ 128 ];
} OSVERSIONINFO;

成员说明:
1)dwOSVersionInfoSize
       以字节为单位,指定这个数据结构的大小。须在调用GetVersionEx(OSVERSIONINFO)函数之前,将这个成员设置为sizeof(OSVERSIONINFO)。
2)dwMajorVersion
       标识操作系统的主版本号。例如,对于Windows NT 3.51版,其主版本号为3;对于Windows NT 4.0版,其主版本号为4。
3)dwMinorVersion
       标识操作系统的次要版本号。例如,对于Windows NT 3.51版,其次要版本号为51;对于Windows NT 4.0版本,其次要版本号为0。
4)dwBuildNumber
       Windows NT:标识操作系统的内部版本号。
Windows 95:低位字标识操作系统数的内部版本号。高位字包含了主要和次要版本号。
5)dwPlatformId
       标识操作系统平台。这个成员可以是下列值之一:
6)szCSDVersion
       Windows NT:包含一个以NULL结尾的字符串,如“Service Pack 3”,就表明系统上安装了最新的Service Pack。如果没有安装Service Pack,该字符串为空。
     Windows 95:包含一个以NULL结尾的字符串,提供了对操作系统的任意补充信息。

应用:

OSVERSIONINFO osVer;osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);::GetVersionEx( &osVer );if( osVer.dwMajorVersion==6 ){GetAudioOuputVolum_Vita();}else{GetAudioOuputVolum_Win7();}

2、vista下获取设备音量

int GetAudioOutputVolumn_Vista(const std::string &deviceName)
{IMMDeviceEnumerator* pEnumerator;IMMDeviceCollection* pCollection = NULL;IMMDevice *pDevice = NULL;IPropertyStore *pProperties=NULL;  IAudioEndpointVolume *pVolumeAPI=NULL;  UINT deviceCount = 0;float fVolume = -1;CoInitializeEx( NULL , COINIT_MULTITHREADED );HRESULT hr=CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),(void**)&pEnumerator);if (hr != S_OK)  {  printf("CoCreateInstance Failed!\n");  return 0;  }  //hr = pEnumerator->EnumAudioEndpoints(eCapture /*eRender*/, DEVICE_STATE_ACTIVE, &pCollection);hr = pEnumerator->EnumAudioEndpoints( eRender , DEVICE_STATE_ACTIVE , &pCollection );if (hr != S_OK)  {  printf("EnumAudioEndpoints Failed!\n");  goto releasepEnumerator;  }  hr = pCollection->GetCount(&deviceCount);  if (hr != S_OK)  {  printf("GetCount Failed!\n");  goto releasepCollection;  }  for (UINT dev=0;dev<deviceCount;dev++)  {  pDevice = NULL;  hr = pCollection->Item(dev,&pDevice);  if (hr == S_OK)  {  hr = pDevice->OpenPropertyStore(STGM_READ,&pProperties);  if (hr == S_OK)  {  PROPVARIANT varName;  PropVariantInit(&varName);  hr = pProperties->GetValue(PKEY_Device_FriendlyName, &varName); if( SUCCEEDED(hr) ){if (varName.vt != VT_LPWSTR || (wstr2str(varName.pwszVal).find(deviceName) != 0)) //传入的值可能不完整,需要前部分匹配{continue;}hr=pDevice->Activate(__uuidof(IAudioEndpointVolume),CLSCTX_ALL,NULL,(void **)(&pVolumeAPI));  if (hr==S_OK)  {  hr = pVolumeAPI->GetMasterVolumeLevelScalar( &fVolume );if (S_OK == hr) break;} }SAFE_RELEASE(pProperties);  }  SAFE_RELEASE(pDevice);  }  }  releasepCollection:  SAFE_RELEASE(pCollection);
releasepEnumerator:  SAFE_RELEASE(pEnumerator);  return  fVolume*100;
}

3、win7下获取设备音量

windows下主要有这几个API:

mixerOpen和mixerClose函数用来打开和关闭混音器设备

mixerGetNumDevs可以确定系统中有多少混音器设备

mixerGetDevCaps函数可以确定混音器设备的能力

mixerGetLineInfo可以检索指定音频线路的信息

mixerGetLineControls用于检索一个或者多个与音频线路相关的控制的通用信息

mixerGetControlDetails用于检索与某个音频线路相关的一个控制的属性

mixerSetControlDetails用于设置制定控制的属性。

int GetAudioOutputVolumn_Win7(const std::string &deviceName)
{MMRESULT          rc;     // 多媒体函数返回结果变量HMIXER            hMixer; // 混合器设备句柄MIXERLINE         mxl;    // 音频线路标准状态信息结构体MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体// 打开混合器设备rc = mixerOpen(&hMixer, // 返回的设备句柄0,       // 单声卡的设备ID为零0,       // 不使用回调机制0,       // 回调函数参数0);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID// 打开混合器设备无错的话,则if (MMSYSERR_NOERROR == rc){// MIXERLINE 结构体变量清零ZeroMemory(&mxl, sizeof(MIXERLINE));mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本// 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERSmxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;// 取得混合器设备的指定线路信息rc = mixerGetLineInfo((HMIXEROBJ)hMixer,&mxl,// 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息MIXER_GETLINEINFOF_COMPONENTTYPE);// 取得混合器设备的指定线路信息成功的话,则if (MMSYSERR_NOERROR == rc){// MIXERCONTROL 结构体变量清零ZeroMemory(&mxc, sizeof(MIXERCONTROL));mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本// MIXERLINECONTROLS 结构体变量清零ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本mxlc.dwLineID = mxl.dwLineID; // 上面取得的声卡音频输出线路标识// 控制类型为控制音量mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小// 取得控制器信息rc = mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,MIXER_GETLINECONTROLSF_ONEBYTYPE);// 取得控制器信息成功的话,则if (MMSYSERR_NOERROR == rc){// 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)// MIXERCONTROLDETAILS 结构体变量清零ZeroMemory(&mxcd, sizeof(mxcd));mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识mxcd.paDetails = &volStruct;        // 音量结构体变量指针mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小mxcd.cChannels = 1;                 // 取得或设置全部通道//  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. // 获得音量值rc = mixerGetControlDetails((HMIXEROBJ)hMixer,&mxcd,MIXER_GETCONTROLDETAILSF_VALUE);if (MMSYSERR_NOERROR == rc){long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;int index = ( volStruct.lValue - mxc.Bounds.lMinimum) /step ;printf("音量:%X", volStruct.lValue);return index;}}}}
}

二、设置设备音量

设置音量和获取音量大部分代码都是相同的,就几句不一样。

1、Vista下设置设备音量

int SetAudioOutputVolum_Vista(int volumnIndex)
{IMMDeviceEnumerator* pEnumerator;IMMDeviceCollection* pCollection = NULL;IMMDevice *pDevice = NULL;IPropertyStore *pProperties=NULL;  IAudioEndpointVolume *pVolumeAPI=NULL;  UINT deviceCount = 0;float fVolume = -1;CoInitializeEx( NULL , COINIT_MULTITHREADED );HRESULT hr=CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),(void**)&pEnumerator);if (hr != S_OK)  {  printf("CoCreateInstance Failed!\n");  return 0;  }  //hr = pEnumerator->EnumAudioEndpoints(eCapture /*eRender*/, DEVICE_STATE_ACTIVE, &pCollection);hr = pEnumerator->EnumAudioEndpoints( eRender , DEVICE_STATE_ACTIVE , &pCollection );if (hr != S_OK)  {  printf("EnumAudioEndpoints Failed!\n");  goto releasepEnumerator;  }  hr = pCollection->GetCount(&deviceCount);  if (hr != S_OK)  {  printf("GetCount Failed!\n");  goto releasepCollection;  }  for (UINT dev=0;dev<deviceCount;dev++)  {  pDevice = NULL;  hr = pCollection->Item(dev,&pDevice);  if (hr == S_OK)  {  hr = pDevice->OpenPropertyStore(STGM_READ,&pProperties);  if (hr == S_OK)  {  PROPVARIANT varName;  PropVariantInit(&varName);  hr = pProperties->GetValue(PKEY_Device_FriendlyName, &varName); if( SUCCEEDED(hr) ){hr=pDevice->Activate(__uuidof(IAudioEndpointVolume),CLSCTX_ALL,NULL,(void **)(&pVolumeAPI));  if (hr==S_OK)  {  float volumnLevel = (float)volumnIndex /100;hr = <span style="color:#ff6666;">pVolumeAPI->SetMasterVolumeLevelScalar( volumnLevel, NULL );</span>} }SAFE_RELEASE(pProperties);  }  SAFE_RELEASE(pDevice);  }  }
releasepCollection:  SAFE_RELEASE(pCollection);
releasepEnumerator:  SAFE_RELEASE(pEnumerator);  return  fVolume*100;
}

2、Win7下设置设备音量

int SetAudioOutputVolum_Win7(int volumnIndex)
{MMRESULT          rc;     // 多媒体函数返回结果变量HMIXER            hMixer; // 混合器设备句柄MIXERLINE         mxl;    // 音频线路标准状态信息结构体MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体// 打开混合器设备rc = mixerOpen(&hMixer, // 返回的设备句柄0,       // 单声卡的设备ID为零0,       // 不使用回调机制0,       // 回调函数参数0);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID// 打开混合器设备无错的话,则if (MMSYSERR_NOERROR == rc){// MIXERLINE 结构体变量清零ZeroMemory(&mxl, sizeof(MIXERLINE));mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本// 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERSmxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;// 取得混合器设备的指定线路信息rc = mixerGetLineInfo((HMIXEROBJ)hMixer,&mxl,// 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息MIXER_GETLINEINFOF_COMPONENTTYPE);// 取得混合器设备的指定线路信息成功的话,则if (MMSYSERR_NOERROR == rc){// MIXERCONTROL 结构体变量清零ZeroMemory(&mxc, sizeof(MIXERCONTROL));mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本// MIXERLINECONTROLS 结构体变量清零ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本mxlc.dwLineID = mxl.dwLineID; // 上面取得的声卡音频输出线路标识// 控制类型为控制音量mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;mxlc.cControls = 1;          // 使用 MIXERCONTROL 结构体变量个数mxlc.pamxctrl = &mxc;        // MIXERCONTROL 结构体变量指针mxlc.cbmxctrl = sizeof(mxc); // MIXERCONTROL 结构体变量字节大小// 取得控制器信息rc = mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,MIXER_GETLINECONTROLSF_ONEBYTYPE);// 取得控制器信息成功的话,则if (MMSYSERR_NOERROR == rc){// 获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum.MIXERCONTROLDETAILS        mxcd;      // 控制器的状态信息MIXERCONTROLDETAILS_SIGNED volStruct; // 音量结构体变量(就一个成员量)// MIXERCONTROLDETAILS 结构体变量清零ZeroMemory(&mxcd, sizeof(mxcd));mxcd.cbStruct = sizeof(mxcd);       // 微软用此办法判断版本mxcd.dwControlID = mxc.dwControlID; // 上面取得的控制器标识mxcd.paDetails = &volStruct;        // 音量结构体变量指针mxcd.cbDetails = sizeof(volStruct); // 音量结构体变量字节大小mxcd.cChannels = 1;                 // 取得或设置全部通道//  获取控制器中的值的音量范围:mxc.Bounds.lMinimum到mxc.Bounds.lMaximum. // 获得音量值rc = mixerGetControlDetails((HMIXEROBJ)hMixer,&mxcd,MIXER_GETCONTROLDETAILSF_VALUE);if (MMSYSERR_NOERROR == rc){long step = ( mxc.Bounds.lMaximum - mxc.Bounds.lMinimum ) /100;<span style="color:#ff6666;"> volStruct.lValue = volumnIndex*step;    // 想要设置的值  rc = mixerSetControlDetails((HMIXEROBJ)hMixer,  &mxcd,  MIXER_SETCONTROLDETAILSF_VALUE);
</span>if (MMSYSERR_NOERROR == rc)  {  return 1;}  }}}}
}

获取与设置windows系统下音频设备音量相关推荐

  1. TF之Windows:Windows系统下设置Tensorflow运行方式为GPU加速运行的详细攻略

    TF之Windows:Windows系统下设置Tensorflow运行方式为GPU加速运行的详细攻略 目录 软件环境 1.第一步安装好CUDA软件程序 2.第二步安装好tensorflow-gpu库 ...

  2. windows系统下,获取固态U盘、固态硬盘SMART信息的小工具-CrystalDiskInfo

    SMART全称为"Self-Monitoring Analysis and Reporting Technology",即"自我监测.分析及报告技术",是一种自 ...

  3. 游戏开发jenkins杂谈系列:windows系统下修改系统时间触发Build periodically设置的定时任务,往前调时间但不再执行定时任务的解决办法

    网上搜了一堆帖子,没有讲到我遇到的这个问题的: windows系统下修改系统时间执行定时任务,例如任务在2020.11.18. 20:36分已经触发了,我将时间调回至2020.11.17 20:35, ...

  4. usb声卡驱动_来自MOTU的温馨提示:如果你的声卡在Windows系统下不稳定,你可以这样做!...

    武汉大学来自MOTU的温馨提示:如果你的声卡在Windows系统下不稳定,你可以这样做! 在我们日常使用外置声卡时,特别是USB接口的外置声卡,相信绝大多数朋友都遇到过声卡掉线.卡死.无故停止工作等各 ...

  5. Windows系统下多显示器模式开发

    转载:开发日记地址 http://blog.sina.com.cn/s/blog_4078ccd60100049a.html 这几天研究了一下Windows系统的多显示器模式的编程,实现了Window ...

  6. 在 Windows 系统下常用的 bat 脚本分享

    以网络配置举例说明,网络连接默认情况下都是 DHCP(自动获取 IP 和 DNS 地址) 模式,但很多情况下,需要我们设置为指定的静态 IP 和 DNS 地址.在 Windows 系统中通常我们都是在 ...

  7. Windows系统下CMD命令

    CMD是command的缩写,即命令行 . 虽然随着计算机产业的发展,Windows 操作系统的应用越来越广泛,DOS 面临着被淘汰的命运,但是因为它运行安全.稳定,有的用户还在使用,所以一般Wind ...

  8. java一键换壁纸_Java 版下载必应每日壁纸并自动设置 Windows 系统桌面(改编自 C# 版)...

    哈哈,好久没有写博客了,已经荒废了,前几天在某 IT 网站看到一个用 C# 写的设置必应每日壁纸为 Windows 系统桌面,看了看源码是通过调用 User32.dll 进行设置的,刚刚最近做的项目更 ...

  9. Windows系统下安装配置 MinGW-w64 开发环境

    MinGW.MinGW-w64 简介 MinGW(全称为,Minimalist GNU for Windows),它实际上是将经典的开源 C语言编译器 GCC 移植到了 Windows 平台下,并且包 ...

最新文章

  1. 什么样的文献有html阅读,有关html的参考文献
  2. string和json转换的简单应用
  3. rtmp服务器与播放器的交互
  4. copy vs. uninitialized_copy
  5. poj1273 最大流
  6. 如何用Unity和Cardboard做一款VR游戏
  7. Centos6.8上httpd配置腾讯云SSL证书
  8. [react] react怎么提高列表渲染的性能?
  9. 不用背景图片,只用css代码实现面包屑样式
  10. 2021年中国单硝酸异山梨酯市场趋势报告、技术动态创新及2027年市场预测
  11. Nginx中间件web服务安装
  12. 幻彩灯 html5,WS2811幻彩灯程序
  13. 微信公众号登录(uniapp)
  14. TRANSFORMER TRANSDUCER: A STREAMABLE SPEECH RECOGNITION MODELWITH TRANSFORMER ENCODERS AND RNN-T
  15. Mysql replace/insert into 插入修改数据
  16. UE5 建模(一)Shapes
  17. 短视频选题的方法脚本结构撰写
  18. 决策树、装袋、提升和随机森林的对比理解
  19. 介绍Java -D 命令行参数
  20. Datawhale成员上榜!

热门文章

  1. JAVA入门Hwork,HBase Java编程入门教程
  2. foss测试_2016年十大FOSS法律案例
  3. 计算机睡眠重启后无法识别网络,电脑睡眠后唤醒电脑没有反应
  4. html设置表格点击变色,js实现表格变色点击行颜色改变
  5. 【Vue3+Vite+TS项目集成ESlint +Prettier实现代码规范检查和代码格式化】
  6. linux gtx驱动程序,Nvidia 418.43 发布,支持GeForce GTX 1660 Ti的Linux图形驱动程序
  7. 现场工程师出手-PCAPHub与云SSH隧道稳妥实现异地LAN IIoT联测
  8. 面试题——正则表达式
  9. TVS二极管DO-15封装型号,有哪些?
  10. 【imessage群发苹果推信】[iMessageSuspic](Apple推送服务)使用信息推送服务