Managed access to microphone input and system volume

Josh Santangelo picture Josh Santangelo · Jul 28, 2009 · Viewed 12k times · Source

I am looking to do three things:

Access data from the microphone. Really all I want to know is the overall volume of the sound sensed by the device.

Set the microphone gain.

Set the system volume.

All of my windows dev experience is C#/WPF, so I'd like to stay managed. I do not need exceptionally high performance or realtime processing or anything.

I've looked around and it seems like SlimDX might be a good wrapper for this, but even there I'm not sure where to start.

Surely it can't be that hard?

Answer

MusiGenesis picture MusiGenesis · Jul 28, 2009

Here's a link that shows how to access the audio mixer in Windows from C#:

http://www.codeguru.com/csharp/csharp/cs_graphics/sound/article.php/c10931

This will let you set the microphone gain and the system volume. The first part is a little more complicated, though. Basically, you need to start recording the input (using DirectSound or the waveInXXXX API [my personal favorite]). As each buffer gets filled with audio, you can calculate the Root Mean Square for the buffer and use this to estimate volume.

Edit: here's a link to a project (that I've used and modified successfully, so I know it works) that shows how to record audio using the waveInXXXX API:

http://www.codeproject.com/KB/audio-video/cswavrec.aspx?df=90&fid=16677&mpp=25&noise=3&sort=Position&view=Quick&select=3005817

Edit 2: and since I'm tired of posting links, here's an actual formula for calculating the Root Mean Square of an audio buffer (the type here is float[], but it can be easily modified to handle short[], which is what you'd normally get from waveInXXXX):

public static float RootMeanSquared(ref float[] audio)
{
    double sumOfSquared = 0;
    for (int i = 0; i < audio.Length; i++)
    {
        sumOfSquared += audio[i] * audio[i];
    }
    return (float)Math.Sqrt(sumOfSquared / (double)audio.Length);
}