#include "StdAfx.h"
#include "MixerWrap.h"
#include <windows.h>
#include <MMSystem.h>
#include <stdlib.h>
#include <string>
#include <iostream>
using namespace std;
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#include <Functiondiscoverykeys_devpkey.h>
#include <comdef.h>
#define SAFE_RELEASE(punk) \
if ((punk) != NULL) \
#define EXIT_ON_ERROR(hres) if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk) if ((punk) != NULL) { (punk)->Release(); (punk) = NULL; }
HRESULT getMicrophoneBoostVolumeLevel(IMMDevice *pEndptDev, IAudioVolumeLevel** ppVolumeLevel)
{
HRESULT hr = S_OK;
DataFlow flow;
IDeviceTopology *pDeviceTopology = NULL;
IConnector *pConnFrom = NULL;
IConnector *pConnTo = NULL;
IPart *pPartPrev = NULL;
IPart *pPartNext = NULL;
*ppVolumeLevel = NULL;
wchar_t microphoneBoostName[] = L"麦克风加强";//if your system language is English,the name is "microphone boost"
if (pEndptDev == NULL)
{
EXIT_ON_ERROR(hr = E_POINTER)
}
// Get the endpoint device's IDeviceTopology interface.
hr = pEndptDev->Activate(
__uuidof(IDeviceTopology), CLSCTX_ALL, NULL,
(void**)&pDeviceTopology);
EXIT_ON_ERROR(hr)
// The device topology for an endpoint device always
// contains just one connector (connector number 0).
hr = pDeviceTopology->GetConnector(0, &pConnFrom);
SAFE_RELEASE(pDeviceTopology)
EXIT_ON_ERROR(hr)
// Make sure that this is a capture device.
hr = pConnFrom->GetDataFlow(&flow);
EXIT_ON_ERROR(hr)
if (flow != Out)
{
// Error -- this is a rendering device.
//EXIT_ON_ERROR(hr = AUDCLNT_E_WRONG_ENDPOINT_TYPE)
}
// Outer loop: Each iteration traverses the data path
// through a device topology starting at the input
// connector and ending at the output connector.
while (TRUE)
{
BOOL bConnected;
hr = pConnFrom->IsConnected(&bConnected);
EXIT_ON_ERROR(hr)
// Does this connector connect to another device?
if (bConnected == FALSE)
{
// This is the end of the data path that
// stretches from the endpoint device to the
// system bus or external bus. Verify that
// the connection type is Software_IO.
ConnectorType connType;
hr = pConnFrom->GetType(&connType);
EXIT_ON_ERROR(hr)
if (connType == Software_IO)
{
break; // finished
}
EXIT_ON_ERROR(hr = E_FAIL)
}
// Get the connector in the next device topology,
// which lies on the other side of the connection.
hr = pConnFrom->GetConnectedTo(&pConnTo);
EXIT_ON_ERROR(hr)
SAFE_RELEASE(pConnFrom)
// Get the connector's IPart interface.
hr = pConnTo->QueryInterface(
__uuidof(IPart), (void**)&pPartPrev);
EXIT_ON_ERROR(hr)
SAFE_RELEASE(pConnTo)
// Inner loop: Each iteration traverses one link in a
// device topology and looks for input multiplexers.
while (TRUE)
{
PartType parttype;
IPartsList *pParts;
// Follow downstream link to next part.
hr = pPartPrev->EnumPartsOutgoing(&pParts);
EXIT_ON_ERROR(hr)
hr = pParts->GetPart(0, &pPartNext);
pParts->Release();
EXIT_ON_ERROR(hr)
hr = pPartNext->GetPartType(&parttype);
EXIT_ON_ERROR(hr)
LPWSTR pName;
if (SUCCEEDED(pPartNext->GetName(&pName)))
{
// Failure of the following call means only that
// the part is not a boost (micrphone boost).
if (wcscmp(microphoneBoostName,pName) == 0)
{
//get IAudioVolumeLevel to control volume
hr = pPartNext->Activate(CLSCTX_ALL, __uuidof(IAudioVolumeLevel), (void**)ppVolumeLevel);
goto Exit;
}
CoTaskMemFree(pName);
}
GUID subType;
pPartNext->GetSubType(&subType);
if (parttype == Connector)
{
// We've reached the output connector that
// lies at the end of this device topology.
hr = pPartNext->QueryInterface(
__uuidof(IConnector),
(void**)&pConnFrom);
EXIT_ON_ERROR(hr)
SAFE_RELEASE(pPartPrev)
SAFE_RELEASE(pPartNext)
break;
}
SAFE_RELEASE(pPartPrev)
pPartPrev = pPartNext;
pPartNext = NULL;
}
}
Exit:
SAFE_RELEASE(pConnFrom)
SAFE_RELEASE(pConnTo)
SAFE_RELEASE(pPartPrev)
SAFE_RELEASE(pPartNext)
return hr;
}
void MixerWrap::MicphoneBoost(bool bIsBoost)
{
int mixerNum ;//总的混音器数量
HMIXER hMixer; //混音器设备句柄
MMRESULT mmr;//函数调用返回
MIXERCAPS MixerCaps; //混音器设备能力信息
MIXERLINE MixerLine;//线路的信息
//获取当前系统总的混音器数量
mixerNum= mixerGetNumDevs();
bool ifFind =false;
for(int i=0;i<mixerNum;i++)
{
//打开混音器,第一个参数是记录混音器的handler,第二个参数是要打开的混音器ID
mmr = mixerOpen(&hMixer, i, 0, 0L, MIXER_OBJECTF_MIXER);
UINT uMxid;
ifFind =false;
//取混音器id,第一个参数是混音器的handler,第二个参数记录混音器的id
//mmr = mixerGetID((HMIXEROBJ)hMixer,&uMxid,MIXER_OBJECTF_HMIXER);
//获取混音器能力特征,如声音控制 和录音控制
mmr = mixerGetDevCaps((UINT)hMixer, &MixerCaps, sizeof(MixerCaps));
for(int j=0;j<MixerCaps.cDestinations;j++)
//MixerCaps.cDestinations表示此混音器设备的audio line目标的数量,
//如一个audio line目标为“音量控制”,另一个audio line目标为“录音控制”。
{
memset(&MixerLine,0,sizeof(MIXERLINE));
MixerLine.cbStruct = sizeof(MixerLine);
MixerLine.dwDestination = j;
// 音量控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
// 录音控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_WAVEIN
//MixerLine.dwComponentType=MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
//mixerGetLineInfo 第三个参数可以是:MIXER_GETLINEINFOF_COMPONENTTYPE,MIXER_GETLINEINFOF_SOURCE,MIXER_GETLINEINFOF_DESTINATION等
//取录音控制
mmr = mixerGetLineInfo((HMIXEROBJ)hMixer, &MixerLine, MIXER_GETLINEINFOF_DESTINATION);
DWORD dwConnections = MixerLine.cConnections;
for ( int count = 0; count < dwConnections; count++ )
{
MixerLine.dwSource = count;
mmr=mixerGetLineInfo((HMIXEROBJ)hMixer,&MixerLine,MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_SOURCE);
if (MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE == MixerLine.dwComponentType)
{
//如果是录音控制的麦克风选项,则跳出
ifFind =true;
break;
}
}
if (ifFind)
{
break;
}
}
if(!ifFind)
continue;
//获取麦克风选项
MIXERLINECONTROLS MixerLineControls;
PMIXERCONTROL paMixerControls;
paMixerControls = (PMIXERCONTROL)malloc(sizeof(MIXERCONTROL) * MixerLine.cControls);
MixerLineControls.cbStruct = sizeof(MixerLineControls);
MixerLineControls.dwLineID = MixerLine.dwLineID;
MixerLineControls.cControls = MixerLine.cControls;
MixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
MixerLineControls.pamxctrl = paMixerControls;
mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls,
MIXER_GETLINECONTROLSF_ALL);
int u ;
ifFind =false;
for ( u = 0; u < MixerLine.cControls; u++)
{
if (wcscmp(paMixerControls[u].szName,_T("麦克风加强"))==0)
{
ifFind =true;
break;
}
}
if (!ifFind)
{
continue;
}
MIXERCONTROL MixerControl;
MixerLineControls.cbStruct = sizeof(MixerLineControls);
MixerLineControls.dwControlID = paMixerControls[u].dwControlID;
MixerLineControls.cbmxctrl = sizeof(MixerControl);
MixerLineControls.pamxctrl = &MixerControl;
mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls, MIXER_GETLINECONTROLSF_ONEBYID);
free(paMixerControls);
MIXERCONTROLDETAILS MixerControlDetails;
PMIXERCONTROLDETAILS_BOOLEAN pMixerControlDetails_Boolean;
pMixerControlDetails_Boolean = (PMIXERCONTROLDETAILS_BOOLEAN)malloc
- 1
- 2
- 3
- 4
- 5
- 6
前往页