参考了网上很多资料,也碰到了许多问题,终于解决了,很开心,把代码贴在这里分享一下:


int DeviceManager::getAudioInputVolumn( const std::string &deviceName )
{
	MMRESULT          rc;     // 多媒体函数返回结果变量
	HMIXER            hMixer; // 混合器设备句柄
	MIXERLINE         mxl;    // 音频线路标准状态信息结构体
	MIXERLINECONTROLS mxlc;   // 音频线路控制器集合信息结构体
	MIXERCONTROL      mxc;    // 单个音频线路控制器信息结构体
	//枚举所有声卡驱动,这个枚举很重要。很多代码调用mixOpen时只是用了第一个设备,即
	//mixerOpen(&hMixer, 0 , 0 ,0 ),但是我在这个设备下调用mixerGetLineInfo出问题了,
	//可能还是跟声卡驱动有关。
	for( int deviceID =0 ; true ; deviceID++ )
	{
		// 打开混合器设备
		rc = mixerOpen(&hMixer, // 返回的设备句柄
			deviceID,       // 单声卡的设备ID为零
			0,       // 不使用回调机制
			0,       // 回调函数参数
			MIXER_OBJECTF_MIXER);      // MIXER_OBJECTF_MIXER宏的值,表示任选有效设备ID
		if( MMSYSERR_NOERROR!=rc )
		{
			//跳出循环
			break;
		}
		// 打开混合器设备无错的话,则
		// MIXERLINE 结构体变量清零
		ZeroMemory(&mxl, sizeof(MIXERLINE));
		mxl.cbStruct = sizeof(MIXERLINE); // 微软用此办法判断版本
		// 指出需要获取的通道,声卡的音频输出用MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
		mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
		// 取得混合器设备的指定线路信息
		rc = mixerGetLineInfo((HMIXEROBJ)hMixer,
			&mxl,
			// 取得MIXERLINE::dwComponentType指定类型的第一个音频线路信息
			MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
		if( rc!=MMSYSERR_NOERROR )
		{
			//无法获取声音输入线路,尝试其他声卡
			continue;
		}
		// 取得混合器设备的指定线路信息成功的话,则
		// 将连接数保存 
		DWORD   dwConnections   =   mxl.cConnections; 
		// 准备获取麦克风设备的ID 
		DWORD   dwLineID = -1; 
		for( DWORD i=0 ; i<dwConnections; i++ )
		{ 
			// 枚举每一个设备,当Source的ID等于当前的迭代记数 
			mxl.dwSource = i;
			// 根据SourceID获得连接的信息 
			rc = mixerGetLineInfo(   (HMIXEROBJ)hMixer,   &mxl, 
				MIXER_OBJECTF_HMIXER   |   MIXER_GETLINEINFOF_SOURCE   ); 
			// 判断函数执行错误 
			if( MMSYSERR_NOERROR==rc )
			{ 
				// 如果当前设备类型是麦克风,则跳出循环。 
				if( mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
				{ 
					dwLineID = mxl.dwLineID; 
					break; 
				}
			}
		}
		// 如果没有找到,返回失败。 
		if( dwLineID==-1 )
		{ 
			//尝试其他声卡
			continue;
		}
		// MIXERCONTROL 结构体变量清零
		ZeroMemory(&mxc, sizeof(MIXERCONTROL));
		mxc.cbStruct = sizeof(mxc); // 微软用此办法判断版本
		// MIXERLINECONTROLS 结构体变量清零
		ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
		mxlc.cbStruct = sizeof(mxlc); // 微软用此办法判断版本
		mxlc.dwLineID = 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;
			}
		}
	}
	return -1;
}