Skip to main content

Getting and Setting Microphone Gain or Microphone Boost on Windows 7 / 8 Programmatically

After hours of searching the net I have finally figured out a way to programmatically get and set the microphone gain (boost) value.

The code mentioned below can be built on VS and does the job of setting gain value.


#include "stdafx.h"
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#include <Functiondiscoverykeys_devpkey.h>
#include "Audioclient.h"
#include "comutil.h"

#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"Microphone Boost";//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;
}

int setMicrophoneBoost(bool bIsBoost, bool bIsIncrease) {
HRESULT hr = NULL;
CoInitialize(NULL);

IMMDeviceEnumerator *deviceEnumerator = NULL;

hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER,
__uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);

IMMDevice *defaultDevice = NULL;

if (hr != S_OK)
{
return 0;
}

hr = deviceEnumerator->GetDefaultAudioEndpoint(eCapture, eMultimedia, &defaultDevice);
deviceEnumerator->Release();

deviceEnumerator = NULL;

IAudioVolumeLevel* pIaudioVolumeLevel;
getMicrophoneBoostVolumeLevel(defaultDevice, &pIaudioVolumeLevel);

defaultDevice->Release();
defaultDevice = NULL;

if (pIaudioVolumeLevel == NULL)
{
return 0;
}

if (bIsBoost)
{
float fMinDb;
float fMaxDb;
float fStepDb;
float pfCurrentDb = 0.0f;
pIaudioVolumeLevel->GetLevelRange(0, &fMinDb, &fMaxDb, &fStepDb);

pIaudioVolumeLevel->GetLevel(0, &pfCurrentDb);
if (bIsIncrease) {
if (pfCurrentDb < fMaxDb) {
pfCurrentDb += fStepDb; // Incrementing DB level By stepincrement
pIaudioVolumeLevel->SetLevel(0, pfCurrentDb, NULL);
}
}
else {
if (pfCurrentDb > fMinDb) {
pfCurrentDb -= fStepDb; // Decrementing DB level By stepincrement
pIaudioVolumeLevel->SetLevel(0, pfCurrentDb, NULL);
}
}
}

return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
int choice;
printf("\r\n Choose 1: to increment gain \r\n Choose 2: to decrement gain \r\n else press any key to return \r\n");
scanf_s("%d", &choice);

switch (choice) {
case 1:
setMicrophoneBoost(true, true); // incrementing db level
break;
case 2:
setMicrophoneBoost(true, false); // decrementing db level
break;
default:
printf("Keeping the microphone gain as is!!!");
break;
}
return 0;
}



User choices are simple, Run the exe from command prompt, enter 1 to increase the microphone boost DB value or 2 to decrease the same.



Comments

  1. Hi DHAV.
    I just copied your code : Getting and Setting Microphone Gain or Microphone Boost on Windows 7 / 8 Programmatically
    It run good on VC++2012 Console.
    Can you help me ? how to run on Vb.net with winform.

    Thankyou very much.

    ReplyDelete
  2. Daianhtai,
    I am sorry, I am not aware of how to get/set mic gain using Vb.net with winform.
    In case if you do not find a method to get/set mic db using winform, I would suggest you to run the above mentioned exe in the background and use post message from your vb.net program to above mentioned exe to increase or decrease mic gain.

    ReplyDelete
  3. Hi DHAV.
    Do you have email ?
    I have some issues ,can you help me

    Thankyou very much.

    ReplyDelete
    Replies
    1. my email : daianhtai2007@gmail.com
      Can you tell me your email ?
      I will send my issue for you by email ,because it's so long.

      Thankyou very much.

      Delete
  4. Do you sure that there's no unused marks in your code? or such error typing?

    ReplyDelete
  5. So I can use the microphone as a mic on xbox live and ps4 for this party members and they pick up me through that likewise? hyperx quadcast

    ReplyDelete

Post a Comment

Popular posts from this blog

Simple example of strong and weak pointers on Android using RefBase class

Here is a simple example explaining the usage of strong and weak pointers using android's RefBase class and the Android.mk to compile the same. Its a modified version of code written by Daniel in the following link. http://himmele.blogspot.com/2012/03/androids-c-reference-counting.html strong_pointer.cpp file:  #include <stdio.h> #include "utils/RefBase.h" namespace android {  class RefTest : public RefBase { public:     RefTest(int32_t id) : mID(id) {         printf("RefTest ctor: %d\n", mID);     }     virtual ~RefTest() {         printf("RefTest dtor: %d\n", mID);     }     int32_t id() const {         return mID;     } private:     int32_t mID; }; int strong_pointer() {     sp<RefTest> ref1 = new RefTest(1);     sp<RefTest> ref5;     {     sp<RefTest> ref2 = new RefTest(2);     ref5 = ref2; // comment this out and check when the destructor of ref2 is cal

Acts Automation Framework For Android

1. Introduction The Android Comms Test Suite, is a lightweight Python-based automation tool set that is used to perform automated testing of current and upcoming Android devices. It provides a simple execution interface; a set of pluggable libraries for accessing commercially available devices, Android devices, and a collection of utility functions to further ease test development. It is an ideal desktop tool for a wireless stack developer or integrator whether exercising a new code path, performing sanity testing, or running extended regression test suites. Included in the tests/google directory are a bundle of tests, many of which can be run with as little as one or two Android devices with wifi, cellular, or bluetooth connectivity, including: 1. Wifi tests for access point interopability, enterprise server integration, WiFi scanning, WiFi auto join, and round trip time. 2. Bluetooth tests for low energy, GATT, SPP, and bonding. 3. Cellular tests for circuit switch and