How to adjust microphone gain from C# (needs to work on XP & W7)...

Posted by Ed on Stack Overflow See other posts from Stack Overflow or by Ed
Published on 2010-06-11T13:11:53Z Indexed on 2010/06/11 13:43 UTC
Read the original article Hit count: 252

Filed under:
|
|

First, note that I know there are a few questions like this already posted; however they don't seem to address the problem adequately. I have a C# application, with all the pInvoke hooks to talk to the waveXXX API, and I'm able to do capture and play back of audio with that. I'm also able to adjust speaker (WaveOut) volume with that API.
The problem is that for whatever reason, that API does not allow me to adjust microphone (WaveIn) volume. So, I managed to find some mixer code that I've also pulled in and access through pInvoke and that allows me to adjust microphone volume, but only on my W7 PC. The mixer code I started with comes from here: http://social.msdn.microsoft.com/Forums/en-US/isvvba/thread/05dc2d35-1d45-4837-8e16-562ee919da85 and it works, but is written to adjust speaker volume. I added the SetMicVolume method shown here...

    public static void SetMicVolume(int mxid, int percentage)
    {
        bool rc;
        int mixer, vVolume;
        MIXERCONTROL volCtrl = new MIXERCONTROL();
        int currentVol;
        mixerOpen(out mixer, mxid, 0, 0, MIXER_OBJECTF_WAVEIN);
        int type = MIXERCONTROL_CONTROLTYPE_VOLUME;
        rc = GetVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE, type, out volCtrl, out currentVol);
        if (rc == false)
        {
            mixerClose(mixer);
            mixerOpen(out mixer, 0, 0, 0, 0);
            rc = GetVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE, type, out volCtrl, out currentVol);
            if (rc == false)    
                throw new Exception("SetMicVolume/GetVolumeControl() failed");
        }
        vVolume = ((int)((float)(volCtrl.lMaximum - volCtrl.lMinimum) / 100.0F) * percentage);
        rc = SetVolumeControl(mixer, volCtrl, vVolume);
        if (rc == false)
            throw new Exception("SetMicVolume/SetVolumeControl() failed");
        mixerClose(mixer);
    }

Note the "second attempt" to call GetVolumeControl(). This is done because on XP, in the first call to GetVolumeControl (refer to site above for that code), the call to mixerGetLineControlsA() fails with XP systems returning MIXERR_INVALCONTROL. Then, with this second attempt using mixerOpen(out mixer, 0, 0, 0, 0), the code doesn't return a failure but the mic gain is unaffected. Note, as I said above, this works on W7 (the second attempt is never executed because it doesn't fail using mixerOpen(out mixer, mxid, 0, 0, MIXER_OBJECTF_WAVEIN)).

I admit to not having a good grasp on the mixer API, so that's what I'm looking into now; however if anyone has a clue why this would work on W7, but not XP, I'd sure like to hear it. Meanwhile, if I figure it out before I get a response, I'll post my own answer...

© Stack Overflow or respective owner

Related posts about c#

Related posts about microphone