winmm lib-windows系统音量控制,API函数调用出错

问题描述

windows系统音量控制,API函数调用出错

最近在开发一个项目过程中遇到一些问题,问题具体如下:
项目中我需要控制系统音量,也就是麦克风以及扬声器音量,于是我找到了一个CVolume类,代码如下:

//Volume.h
include "MMSystem.h"
define HMIXER_NUM_MAX 10
class CVolume
{
public:
CVolume(void);
public:
~CVolume(void);

public:
HMIXER m_hMixer[HMIXER_NUM_MAX];
BOOL m_barrOpened[HMIXER_NUM_MAX];
HMIXER m_hMixerMic;
HMIXER m_hMixerSpk;
int m_iMixerNums;
MIXERLINE m_MixerLineMicrophone;

BOOL MixerOpen();
void MixerClose();
BOOL m_bIsOpen;
BOOL GetMicrophoneID();
BOOL GetMicrophoneLevel(DWORD* dwLevel, DWORD* dwLevelMax);
BOOL SetMicrophoneLevel(DWORD dwLevel);
BOOL GetSpeakerLevel(DWORD* dwLevel, DWORD* dwLevelMax);
BOOL SetSpeakerLevel(DWORD dwLevel);

};
//Volume.cpp
include "stdafx.h"
include "Volume.h"
CVolume::CVolume(void)
{
m_bIsOpen = FALSE;
m_iMixerNums = 0;
m_hMixerMic = 0;
m_hMixerSpk = 0;
for (int i = 0; i < HMIXER_NUM_MAX; i ++)
m_barrOpened[i] = FALSE;
}

CVolume::~CVolume(void)
{
MixerClose();
}

BOOL CVolume::MixerOpen()
{
m_iMixerNums = mixerGetNumDevs();
if (mixerGetNumDevs() < 1)
return FALSE;
m_iMixerNums = min(m_iMixerNums, HMIXER_NUM_MAX);
m_bIsOpen = FALSE;
for (int i = 0; i < m_iMixerNums; i ++)
{
MMRESULT mmresult = mixerOpen(&m_hMixer[i], (UINT)i, 0, 0, MIXER_OBJECTF_MIXER);

if (mmresult == MMSYSERR_NOERROR)
{
m_barrOpened[i] = TRUE;
m_bIsOpen = TRUE;
}
}
return m_bIsOpen;
}

void CVolume::MixerClose()
{
if (m_bIsOpen)
{
for (int i = 0; i < m_iMixerNums; i ++)
{
if (m_barrOpened[i])
{
mixerClose(m_hMixer[i]);
m_barrOpened[i] = FALSE;
}
}
m_bIsOpen = FALSE;
}
}

BOOL CVolume::GetMicrophoneID()
{
MMRESULT mmresult;
if (!m_bIsOpen)
return FALSE;
m_MixerLineMicrophone.cbStruct = sizeof(m_MixerLineMicrophone);
m_MixerLineMicrophone.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
for (int i = 0; i < m_iMixerNums; i ++)
{
mmresult = mixerGetLineInfo((HMIXEROBJ)m_hMixer[i], &m_MixerLineMicrophone,
MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE);
if (mmresult == MMSYSERR_NOERROR)
{
m_hMixerMic = m_hMixer[i];
break;
}
}
if (m_hMixerMic == 0)
return FALSE;
DWORD dwConnections = m_MixerLineMicrophone.cConnections;
DWORD dwLineID = 0;
for (DWORD i = 0; i < dwConnections; i++)

{

m_MixerLineMicrophone.dwSource = i;

MMRESULT mr = mixerGetLineInfo((HMIXEROBJ)m_hMixerMic, &m_MixerLineMicrophone,

MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_SOURCE);

if (mr != MMSYSERR_NOERROR)

{

break;

}

if (m_MixerLineMicrophone.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE)

{

dwLineID = m_MixerLineMicrophone.dwLineID;

break;

}

}

if (dwLineID == 0)

{

return FALSE;

}
return TRUE;
}

BOOL CVolume::GetMicrophoneLevel(DWORD* dwLevel, DWORD* dwLevelMax)
{
MMRESULT mmresult;
MIXERCONTROL mxc;

MIXERLINECONTROLS mxlc;
if (!m_bIsOpen)
return FALSE;
mxlc.cbStruct = sizeof(MIXERLINECONTROLS);

mxlc.dwLineID = m_MixerLineMicrophone.dwLineID;

mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;

mxlc.cControls = 1;

mxlc.cbmxctrl = sizeof(MIXERCONTROL);

mxlc.pamxctrl = &mxc;

mmresult = mixerGetLineControls(

reinterpret_cast(m_hMixerMic),

&mxlc,

MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE);

if (mmresult != MMSYSERR_NOERROR)

return FALSE;
MIXERCONTROLDETAILS_UNSIGNED mxcdVolume;

MIXERCONTROLDETAILS mxcd;

mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);

mxcd.dwControlID = mxc.dwControlID;

mxcd.cChannels = 1;

mxcd.cMultipleItems = 0;

mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);

mxcd.paDetails = &mxcdVolume;

mmresult = mixerGetControlDetails(

reinterpret_cast(m_hMixerMic),

&mxcd,

MIXER_GETCONTROLDETAILSF_VALUE);

if (mmresult != MMSYSERR_NOERROR)

return FALSE;
*dwLevel = mxcdVolume.dwValue;
*dwLevelMax = mxc.Bounds.dwMaximum;
return TRUE;
}

BOOL CVolume::SetMicrophoneLevel(DWORD dwLevel)
{
MMRESULT mmresult;
MIXERCONTROL mxc;

MIXERLINECONTROLS mxlc;
if (!m_bIsOpen)
return FALSE;
mxlc.cbStruct = sizeof(MIXERLINECONTROLS);

mxlc.dwLineID = m_MixerLineMicrophone.dwLineID;

mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;

mxlc.cControls = 1;

mxlc.cbmxctrl = sizeof(MIXERCONTROL);

mxlc.pamxctrl = &mxc;

mmresult = mixerGetLineControls(

reinterpret_cast(m_hMixerMic),

&mxlc,

MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE);

if (mmresult != MMSYSERR_NOERROR)

return FALSE;
MIXERCONTROLDETAILS_UNSIGNED mxcdVolume_Set =

{

dwLevel

};

MIXERCONTROLDETAILS mxcd_Set;

mxcd_Set.cbStruct = sizeof(MIXERCONTROLDETAILS);

mxcd_Set.dwControlID = mxc.dwControlID;

mxcd_Set.cChannels = 1;

mxcd_Set.cMultipleItems = 0;

mxcd_Set.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);

mxcd_Set.paDetails = &mxcdVolume_Set;

mmresult = mixerSetControlDetails(reinterpret_cast(m_hMixerMic),

&mxcd_Set,

MIXER_OBJECTF_HMIXER |

MIXER_SETCONTROLDETAILSF_VALUE);

return (mmresult == MMSYSERR_NOERROR);
}

BOOL CVolume::GetSpeakerLevel(DWORD* dwLevel, DWORD* dwLevelMax)
{
MMRESULT mmr;
MIXERLINE mxl;
MIXERCONTROL mxc;
MIXERLINECONTROLS mxlc;
MIXERCONTROLDETAILS mxcd;
MIXERCONTROLDETAILS_UNSIGNED mxcdVolume;
if (!m_bIsOpen)
return FALSE;
for (int i = 0; i < m_iMixerNums; i ++)
{
mxl.cbStruct = sizeof(mxl);
mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
mmr = mixerGetLineInfo((HMIXEROBJ)m_hMixer[i], &mxl, MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
if ( mmr == MMSYSERR_NOERROR)
{
m_hMixerSpk = m_hMixer[i];
break;
}
}
if (m_hMixerSpk == 0)
return FALSE;
mxlc.cbStruct = sizeof(mxlc);
mxlc.dwLineID = mxl.dwLineID;
mxlc.cControls = mxl.cControls;
mxlc.dwControlID = MIXERCONTROL_CONTROLTYPE_VOLUME;
mxlc.cbmxctrl = sizeof(mxc);
mxlc.pamxctrl = &mxc;
mmr = mixerGetLineControls((HMIXEROBJ)m_hMixerSpk, &mxlc, MIXER_OBJECTF_HMIXER|MIXER_GETLINECONTROLSF_ONEBYTYPE);
mxcd.cbStruct = sizeof(mxcd);
mxcd.dwControlID = mxc.dwControlID;
mxcd.cChannels = 1;
mxcd.cMultipleItems = 0;
mxcd.cbDetails = sizeof(mxcdVolume);
mxcd.paDetails = &mxcdVolume;
mmr = mixerGetControlDetails((HMIXEROBJ)m_hMixerSpk, &mxcd,
MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE);

if (mmr != MMSYSERR_NOERROR)

return FALSE;
*dwLevel = mxcdVolume.dwValue;
*dwLevelMax = mxc.Bounds.dwMaximum;
return TRUE;
}

BOOL CVolume::SetSpeakerLevel(DWORD dwLevelPercent)
{
MMRESULT mmr;
MIXERLINE mxl;
MIXERCONTROL mxc;
MIXERLINECONTROLS mxlc;
MIXERCONTROLDETAILS mxcd;
MIXERCONTROLDETAILS_UNSIGNED mxcdVolume;
if (!m_bIsOpen)
return FALSE;
mxl.cbStruct = sizeof(mxl);
mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
mmr = mixerGetLineInfo((HMIXEROBJ)m_hMixerSpk, &mxl, MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
mxlc.cbStruct = sizeof(mxlc);
mxlc.dwLineID = mxl.dwLineID;
mxlc.cControls = mxl.cControls;
mxlc.dwControlID = MIXERCONTROL_CONTROLTYPE_VOLUME;
mxlc.cbmxctrl = sizeof(mxc);
mxlc.pamxctrl = &mxc;
mmr = mixerGetLineControls((HMIXEROBJ)m_hMixerSpk, &mxlc, MIXER_OBJECTF_HMIXER|MIXER_GETLINECONTROLSF_ONEBYTYPE);
MIXERCONTROLDETAILS_UNSIGNED mxcdVolume_Set =

{

dwLevelPercent

};

mxcd.cbStruct = sizeof(mxcd);
mxcd.dwControlID = mxc.dwControlID;
mxcd.cChannels = 1;
mxcd.cMultipleItems = 0;
mxcd.cbDetails = sizeof(mxcdVolume);
mxcd.paDetails = &mxcdVolume_Set;
mmr = mixerSetControlDetails((HMIXEROBJ)m_hMixerSpk, &mxcd,
MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE);

return (mmr == MMSYSERR_NOERROR);

}
可以看到这个类结构还是非常简单明了的,但是却出现了意想不到的错误,我在基于对话框项目程序中调用volumeControl.MixerOpen()函数时,volumeControl是我添加的CVolume类,编译连接都没有出现问题,在运行程序时出现:Unhandled exception at 0x0002bfc0 in CSHowlingSupress.exe: 0xC0000005: Access violation.
我知道问题肯定是出现在MixerOpen函数中,于是我在MixerOpen入口处设置断点,这时我发现mixerGetNumDevs函数 CXX0017: Error: symbol "mixerGetNumDevs" not found。 也就是说这个函数根明就没有申明,调用了空指针。但是我实在搞不明白,mixerGetNumDevs不是WIN API 函数吗,需要用的库函数Winmm.lib我也加在项目属性中添加了,怎么还会出现这种问题呢,我无语了。我电脑安装了有两块声卡,Realtek High Definition Audio和RME Fireface UC。哪位大神能帮我看看啊,感激不尽!

时间: 2024-09-29 08:11:30

winmm lib-windows系统音量控制,API函数调用出错的相关文章

android音频系统音量控制探讨

      android音频系统音量控制上,没有考虑到控制模拟音频信号的问题,笔者在项目中要控制FM,voice incall的时候很不好处理.android对数字信号有很好的处理,可以用software来调节音量,省去硬件的控制,但是对于模拟信号不能一起控制了,笔者采用在android中不使用软件条件音量,因为如果采用软件音量,必然需要把音频的codec芯片设置的默认值提高,但是一提高,噪声就会增大,音效不好.但是android音频设计的时候就没有考虑好这一点,所以在改了音量直接控制code

用C# 控制Windows系统音量的实现方法_C 语言

C#开发Windows应用程序中经常需要去控制系统的音量,分两种方式: 1.使用Win Api控制 2.使用C++ dll控制 Win Api控制: 使用user32.dll和winmm.dll都可以控制系统音量,区别是Win系统的版本.winmm.dll Xp环境下可用,user32.dll Vista及以上版本. C++ dll控制: CoreAudioApi 是C++ 第三方封装了音量控制,网上下载DLL后再项目中引用即可使用.CoreAudioApi Vista及以上版本支持. 下面给出

C++程序中使用Windows系统Native Wifi API的基本教程_C 语言

Windows应用想要实现连接wifi,监听wifi信号,断开连接等功能,用NativeWifi API是个不错的选择. 打开MSDN,搜索NativeWifi Api,找到Native Wifi页.在这里. 信息量很大,如果像我着急实现上述功能,看海量的文档有些来不及.如果直接给我例子,在运行中调试,阅读代码,效率会更高. 但是,我并没有成功.首先,Sample在SDK中,参见这里.我下载几次都失败了,最后放弃这条路.后来同事给了我一份Sample,我不敢确定是否就是这个,但是代码写的也是很晦

VISTA音量控制 [翻译]_Vista

原文:https://blogs.msdn.com/larryosterman/archive/2005/12/15/504158.aspx 作者:larryosterman 翻译:Tony Qu (来自BluePrint翻译团队) 在Vista之前,所有对应用程序的控制都是系统级的--当你用wave volumn API改变音量的时候,你会同时改变硬件(声卡)的音量,因此会影响系统中所有的应用程序.这样做的问题在于,对于绝大部分应用程序来说,这是完全错误的行为.该行为是老的Windows 3.

android-Android视频声音控制,videoview静音不影响系统音量的代码实现

问题描述 Android视频声音控制,videoview静音不影响系统音量的代码实现 Android中videoview能静音而不影响系统音量吗?如何做到? Android中有这样的视频组件吗?(不受系统音量影响,自己控制自己的音量) 解决方案 楼主解决了吗,我也遇到了这个问题 解决方案二: 楼主解决了吗?我现在也遇到了这个问题,同求解决方案!!! 解决方案三: 楼主解决了吗?我现在也遇到了这个问题,同求解决方案!!!

windows 系统 鲜为人知的宝藏

window All Users 这里记录的是Window的用户以及这些用户个人设定的开始菜单及桌面等信息.   Command 在这个目录下有着许多的DOS的常用命令,例如debug, format 等.可别小看这些老廉颇呀,在许多关键时刻还得靠他们哟.      Config 用于存放Windows中硬件配制文件.     Cursors 这是存放Windows光标的目录.     Desktop 除了"我的电脑"."我的文档"这几个系统图标外其它由程序和文档建

Windows系统技巧总汇

本教程为大家介绍一些windows中不为人知的小技巧,可以让你更便捷的使用计算机,下面一起来看看吧. 1.影音文件在xp中无法删除 很多情况下是因为预览功能出了问题.开始 运行中输入并执行"REGSVR32 /U SHMEDIA.DLL",取消息预览. 恢复时运行"REGSVR32 SHMEDIA.DLL" 其实就是去掉预览功能 2.注册表解锁 方法一: REGEDIT4 [HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurre

linux/windows系统如何安装php-gd扩展库

昨天有位客户咨询我一个问题,他在使用然之OA 系统时涉及到图片显示时提示下面错误窗口.看到这个错误提示,我们肯定都会想到是不是PHP的gd库未安装,但是这位朋友说他用phpinfo查看了下PHP环境,发现gd扩展已存在,而且问题依旧存在,所以才头疼问题出在哪里.下面是这位朋友给我的截图: 看到这里,可能一些细心的朋友已经发现问题所在了,很明显,这位用户的gd扩展安装得不完整.这里我先直接给大家展示gd库完整安装后的截图: 所以我们在检查PHP环境,要看一下扩展是否安装齐全.完整,针对上面的问题,

【漏洞公告】高危:Windows系统 SMB/RDP远程命令执行漏洞

2017年4月14日,国外黑客组织Shadow Brokers发出了NSA方程式组织的机密文档,包含了多个Windows 远程漏洞利用工具,该工具包可以可以覆盖全球70%的Windows服务器,为了确保您在阿里云上的业务安全,请您关注,具体漏洞详情如下: 漏洞编号: 暂无 漏洞名称: Windows系统多个SMB\RDP远程命令执行漏洞官方评级: 高危 漏洞描述: 国外黑客组织Shadow Brokers发出了NSA方程式组织的机密文档,包含了多个Windows 远程漏洞利用工具,该工具包可以可