Windows 7控制麦克风的播放音量 [英] windows 7 control playback volume of microphone

查看:178
本文介绍了Windows 7控制麦克风的播放音量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图调整麦克风的播放音量;但不幸的是我做不到.我可以使用NAudio库控制麦克风的录制音量,但我想控制播放音量.有什么方法可以控制Windows 7上的麦克风播放音量.C ++或C#解决方案对我来说都是可以接受的.

I was trying to adjust playback volume level of microphone; but unfortunately I couldn't. I can control recording volume of microphone by using NAudio library but I want to control playback volume. Is there any way to control microphone playback volume on windows 7. Either C++ or C# solution is acceptable for me.

以下是解决我的问题的一些尝试:

http://www.computercabal .com/2010/11/mute-microphone-from-c-on-windows.html (这个人写了一个小库,可以使麦克风的录音音量静音).

http://www.computercabal.com/2010/11/mute-microphone-from-c-on-windows.html (This guy wrote a small library that can mute microphone recording volume).

NAudio-无法设置线路控制静音值(此解决方案只能使麦克风的录音音量静音).

NAudio - Cannot set line control mute value (This solution is able to mute only microphone recording volume).

这是通过使用NAudio解决我的问题的另一种令人沮丧的尝试,它也仅使麦克风录音电平静音:

This is another frustrating attempt to solve my problem by using NAudio, and this mutes only microphone recording level,too:

MMDeviceEnumerator DevEnum = new MMDeviceEnumerator();

MMDeviceCollection devices = DevEnum.EnumerateAudioEndPoints(DataFlow.Capture, DeviceState.Active);

MMDevice micDevice = null;

for (int i = 0; i < devices.Count; i++)
{
    MMDevice deviceAt = devices[i];
    Console.WriteLine(deviceAt.FriendlyName);
    if (deviceAt.FriendlyName.ToLower().StartsWith("mikrofon"))
    {
        micDevice = deviceAt;
    }
}

micDevice.AudioEndpointVolume.Mute = true;

推荐答案

我遇到了同样的问题,并且已经通过使用IDeviceTopology接口找到了答案.

I had the same issue and I have found the answer by using the IDeviceTopology interface.

我使用了浮动在网络上的WalkTreeBackwardsFromPart示例.

I used the WalkTreeBackwardsFromPart example that is floating around the web.

首先,您需要获取渲染设备(扬声器)的零件.

First you have to get the Parts for the Render device (Speaker).

HRESULT hr = CoInitialize(NULL);
if (FAILED(hr)) {
    printf("Failed CoInitializeEx: hr = 0x%08x\n", hr);
    return __LINE__;
}

// get default render endpoint
IMMDeviceEnumerator *pEnum = NULL;
hr = CoCreateInstance(
    __uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),
    (void**)&pEnum
    );
if (FAILED(hr)) {
    printf("Couldn't get device enumerator: hr = 0x%08x\n", hr);
    CoUninitialize();
    return __LINE__;
}
IMMDevice *pDevice = NULL;
IMMDeviceCollection *pDevices = NULL;

hr = pEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pDevices);

UINT  count;
hr = pDevices->GetCount(&count);

// Each loop prints the name of an endpoint device.
for (ULONG i = 0; i < count; i++)
{

        //hr = pEnum->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
    hr = pDevices->Item(i, &pDevice);
    if (FAILED(hr)) {
        printf("Couldn't get default render device: hr = 0x%08x\n", hr);
        pEnum->Release();
        CoUninitialize();
        return __LINE__;
    }
    pEnum->Release();

    // get device topology object for that endpoint
    IDeviceTopology *pDT = NULL;
    hr = pDevice->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&pDT);
    if (FAILED(hr)) {
        printf("Couldn't get device topology object: hr = 0x%08x\n", hr);
        pDevice->Release();
        CoUninitialize();
        return __LINE__;
    }
    pDevice->Release();

    // get the single connector for that endpoint
    IConnector *pConnEndpoint = NULL;
    hr = pDT->GetConnector(0, &pConnEndpoint);
    if (FAILED(hr)) {
        printf("Couldn't get the connector on the endpoint: hr = 0x%08x\n", hr);
        pDT->Release();
        CoUninitialize();
        return __LINE__;
    }
    pDT->Release();

    // get the connector on the device that is
    // connected to
    // the connector on the endpoint
    IConnector *pConnDevice = NULL;
    hr = pConnEndpoint->GetConnectedTo(&pConnDevice);
    if (FAILED(hr)) {
        printf("Couldn't get the connector on the device: hr = 0x%08x\n", hr);
        pConnEndpoint->Release();
        CoUninitialize();
        return __LINE__;
    }
    pConnEndpoint->Release();

    // QI on the device's connector for IPart
    IPart *pPart = NULL;
    hr = pConnDevice->QueryInterface(__uuidof(IPart), (void**)&pPart);
    if (FAILED(hr)) {
        printf("Couldn't get the part: hr = 0x%08x\n", hr);
        pConnDevice->Release();
        CoUninitialize();
        return __LINE__;
    }
    pConnDevice->Release();

    // all the real work is done in this function
    hr = WalkTreeBackwardsFromPart(pPart);
    if (FAILED(hr)) {
        printf("Couldn't walk the tree: hr = 0x%08x\n", hr);
        pPart->Release();
        CoUninitialize();
        return __LINE__;
    }
    pPart->Release();
}

魔术发生的地方是调用WalkTreeBackwardsFromPart的最后一部分.

The last part there where it call WalkTreeBackwardsFromPart is where the magic happens.

我在这里的测试代码所做的只是浏览传入的零件,并找到一个标有"Front Pink In"(这是麦克风的插孔)的零件,当显示音量"时,它将设置该零件的音量.这不是最好的代码,但我只是想找到合适的部分.

What my test code here does is just go through the Incoming Parts and finds the one labeled "Front Pink In" (this is the the jack for the mic) and when the Volume is being displayed it sets the volume for that part. This is not the greatest code but I was just trying to find the right part.

HRESULT WalkTreeBackwardsFromPart(IPart *pPart, int iTabLevel /* = 0 */) {
HRESULT hr = S_OK;

Tab(iTabLevel);
LPWSTR pwszPartName = NULL;
hr = pPart->GetName(&pwszPartName);
if (FAILED(hr)) {
    printf("Could not get part name: hr = 0x%08x", hr);
    return hr;
}
printf("Part name: %ws\n", *pwszPartName ? pwszPartName : L"(Unnamed)");
//CoTaskMemFree(pwszPartName);

// see if this is a volume node part
IAudioVolumeLevel *pVolume = NULL;
hr = pPart->Activate(CLSCTX_ALL, __uuidof(IAudioVolumeLevel), (void**)&pVolume);
if (E_NOINTERFACE == hr) {
    // not a volume node
} else if (FAILED(hr)) {
    printf("Unexpected failure trying to activate IAudioVolumeLevel: hr = 0x%08x\n", hr);
    return hr;
} else {
    // it's a volume node...
    hr = DisplayVolume(pVolume, iTabLevel, wcscmp(L"Front Pink In", pwszPartName) == 0);
    if (FAILED(hr)) {
        printf("DisplayVolume failed: hr = 0x%08x", hr);
        pVolume->Release();
        return hr;
    }

    if (wcscmp(L"Microphone Boost", pwszPartName) == 0)
    {
        SetVolume(pVolume);
    }

    pVolume->Release();
}

CoTaskMemFree(pwszPartName);

// see if this is a mute node part
IAudioMute *pMute = NULL;
hr = pPart->Activate(CLSCTX_ALL, __uuidof(IAudioMute), (void**)&pMute);
if (E_NOINTERFACE == hr) {
    // not a mute node
} else if (FAILED(hr)) {
    printf("Unexpected failure trying to activate IAudioMute: hr = 0x%08x\n", hr);
    return hr;
} else {
    // it's a mute node...
    hr = DisplayMute(pMute, iTabLevel);
    if (FAILED(hr)) {
        printf("DisplayMute failed: hr = 0x%08x", hr);
        pMute->Release();
        return hr;
    }

    pMute->Release();
}

// get the list of incoming parts
IPartsList *pIncomingParts = NULL;

//get the list of incoming parts    
//hr = pPart->EnumPartsOutgoing(&pIncomingParts);
hr = pPart->EnumPartsIncoming(&pIncomingParts);
if (E_NOTFOUND == hr) {
    // not an error... we've just reached the end of the path
    Tab(iTabLevel);
    printf("No incoming parts at this part\n");
    return S_OK;
}
else
{

    if (FAILED(hr)) {
        printf("Couldn't enum incoming parts: hr = 0x%08x\n", hr);
        return hr;
    }
    UINT nParts = 0;
    hr = pIncomingParts->GetCount(&nParts);
    if (FAILED(hr)) {
        printf("Couldn't get count of incoming parts: hr = 0x%08x\n", hr);
        pIncomingParts->Release();
        return hr;
    }

    // walk the tree on each incoming part recursively
    for (UINT n = 0; n < nParts; n++) {
        IPart *pIncomingPart = NULL;
        hr = pIncomingParts->GetPart(n, &pIncomingPart);
        if (FAILED(hr)) {
            printf("Couldn't get part #%u (0-based) of %u (1-basedSmile hr = 0x%08x\n", n, nParts, hr);
            pIncomingParts->Release();
            return hr;
        }

        hr = WalkTreeBackwardsFromPart(pIncomingPart, iTabLevel + 1);
        if (FAILED(hr)) {
            printf("Couldn't walk tree on part #%u (0-based) of %u (1-basedSmile hr = 0x%08x\n", n, nParts, hr);
            pIncomingPart->Release();
            pIncomingParts->Release();
            return hr;
        }
        pIncomingPart->Release();
    }

    pIncomingParts->Release();
}

return S_OK;
}

HRESULT SetVolume(IAudioVolumeLevel *pVolume)
{
HRESULT hr = S_OK;
UINT nChannels = 0;

hr = pVolume->SetLevel(0,20.0,NULL);
return hr;
}

HRESULT DisplayVolume(IAudioVolumeLevel *pVolume, int iTabLevel, bool setVolume) {
HRESULT hr = S_OK;
UINT nChannels = 0;

hr = pVolume->GetChannelCount(&nChannels);

if (FAILED(hr)) {
    printf("GetChannelCount failed: hr = %08x\n", hr);
    return hr;
}

for (UINT n = 0; n < nChannels; n++) {
    float fMinLevelDB, fMaxLevelDB, fStepping, fLevelDB;

    hr = pVolume->GetLevelRange(n, &fMinLevelDB, &fMaxLevelDB, &fStepping);
    if (FAILED(hr)) {
        printf("GetLevelRange failed: hr = 0x%08x\n", hr);
        return hr;
    }

    hr = pVolume->GetLevel(n, &fLevelDB);
    if (FAILED(hr)) {
        printf("GetLevel failed: hr = 0x%08x\n", hr);
        return hr;
    }

    float levetToSet = fMinLevelDB + ((fMaxLevelDB-fMinLevelDB) * 50 /100.0);

    if (setVolume && nChannels == 2)
    {
        if (n == 0)
        {
            hr = pVolume->SetLevel(n, fMinLevelDB,NULL);
        }
        else
        {
            hr = pVolume->SetLevel(n, fMaxLevelDB,NULL);
        }
    }

    Tab(iTabLevel);
    printf(
        "Channel %u volume is %.3f dB (range is %.3f dB to %.3f dB in increments of %.3f dB)\n",
        n, fLevelDB, fMinLevelDB, fMaxLevelDB, fStepping
        );
}

return S_OK;
}

HRESULT DisplayMute(IAudioMute *pMute, int iTabLevel) {
HRESULT hr = S_OK;
BOOL bMuted = FALSE;

hr = pMute->GetMute(&bMuted);

if (FAILED(hr)) {
    printf("GetMute failed: hr = 0x%08x\n", hr);
    return hr;
}

Tab(iTabLevel);
printf("Mute node: %s\n", bMuted ? "MUTED" : "NOT MUTED");

return S_OK;
}

void Tab(int iTabLevel) {
if (0 >= iTabLevel) { return; }
printf("\t");
Tab(iTabLevel - 1);
}

无论如何,当我设置此音量时,它都会更改HD Audio Manager麦克风屏幕上的播放音量L和R和音量滑块.

Anyways when I was setting this volume it was changing Playback Volume L and R and volume slider on the HD Audio Manager Mic Screen.

这篇关于Windows 7控制麦克风的播放音量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆