利用MIXER获取麦克风录音音量

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

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
// 枚举每一个设备,当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;
}
转载自 http://sunerok.blog.163.com/blog/static/231096422010112815525949/

你可能感兴趣的:(多媒体,微软,多媒体)