Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Managed access to microphone input and system volume

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?

like image 433
Josh Santangelo Avatar asked Jul 28 '09 02:07

Josh Santangelo


People also ask

How do I fix change my Privacy settings to access my microphone?

Here's how: Select Start > Settings > Privacy > Microphone . In Allow access to the microphone on this device, select Change and make sure Microphone access for this device is turned on.


2 Answers

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);
}
like image 89
MusiGenesis Avatar answered Oct 11 '22 22:10

MusiGenesis


Unfortunately you can't reliably read (or render) data from managed code unless you're willing to live with serious latency (on the order of .5 second). The problem is that the CLR can interrupt your process for 250 milliseconds at a time without warning. Normally this doesn't matter, but when you're trying to do isochronous processing it can be a significant issue.

like image 30
ReinstateMonica Larry Osterman Avatar answered Oct 11 '22 22:10

ReinstateMonica Larry Osterman