管理麦克风输入和系统音量的访问

5

我希望做三件事:

访问麦克风数据。实际上,我只想知道设备感应到的声音的整体音量。

设置麦克风增益。

设置系统音量。

我所有的Windows开发经验都是C#/WPF,所以我想保持托管状态。我不需要特别高的性能或实时处理等任何东西。

我已经查找了一些资料,似乎SlimDX可能是一个很好的封装器,但即使在那里,我也不确定从哪里开始。

肯定不会很难吧?

4个回答

7
以下是如何从C#中访问Windows音频混合器的链接:http://www.codeguru.com/csharp/csharp/cs_graphics/sound/article.php/c10931。这将使您能够设置麦克风增益和系统音量。不过,第一部分会比较复杂。基本上,您需要开始录制输入(使用DirectSound或waveInXXXX API [我个人最喜欢的API])。随着每个缓冲区被音频填充,您可以计算该缓冲区的均方根并使用它来估算音量。
编辑:以下是一个项目的链接(我已经成功使用并修改过,所以我知道它有效),展示了如何使用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 编辑2:由于我厌倦了发布链接,以下是实际的公式,用于计算音频缓冲区的均方根(此处类型为float[],但可以轻松修改以处理从waveInXXXX获得的short[]):
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);
}

感谢您提供的信息丰富的答案。然而,当我点击“开始”按钮时,该示例立即崩溃。 - Josh Santangelo
哪一个?第一个还是第二个? - MusiGenesis
为什么浮点数数组参数是 ref 类型?值类型不应该足够吗? - Andreas Grech
@Dreas:我写了很多以float[]数组作为参数的函数。通常这些函数只是修改现有的数组,但有时它们会根据我的需求(混响就是一个例子)修改现有的数组或创建一个新的更大的数组。为了做到这一点,我必须通过引用传递输入,所以这已经成为了一种习惯。你说得对,这个函数没有ref关键字也可以正常工作。 - MusiGenesis
函数RootMeanSquared只有在信号的均值为0时才是正确的,因此它上面没有连续的分量。通常情况下是这样的,但也有一些情况不是这样的。 - Angelo Mascaro

4

很遗憾,除非您愿意忍受严重的延迟(大约0.5秒),否则无法可靠地读取(或呈现)托管代码中的数据。问题在于CLR可以随时中断您的进程250毫秒。通常这并不重要,但当您尝试进行等时处理时,它可能是一个重要问题。


我写了一个C#应用程序,使用P/Invoke调用了waveIn*并在(我认为的)实时情况下呈现了频谱图。它似乎没有这种程度的延迟问题。我只是幸运没有遇到这个问题吗? - MusiGenesis
3
你可能没有耗尽内存或触发垃圾回收循环。这还取决于你使用的操作系统。在Vista上,波形API有约100毫秒的延迟,这使它们更能抵御故障。而在XP和Win7上,它们的延迟约为30毫秒,更容易出现故障。 - Larry Osterman
1
我正在运行Vista。谢谢,这是很好的知识。我的软件合成器不支持实时处理,但我正在考虑编写一个支持实时处理的版本。这种延迟几乎让这个想法变得不可能(我假设这些延迟也适用于waveOut*?),因为我的声音生成过程已经相对昂贵。 - MusiGenesis
我认为因为你正在使用P/Invoke而不是托管库,所以这不是太大的问题...除非我错了,如果是这样,请有人纠正我。 - Mahmoud Al-Qudsi
1
@MahmoudAl-Qudsi 调用本身不会被延迟,因为它是非托管的,但结果的处理可能会延迟... - Basic

3
你可以使用 NAudio 在托管的C#中捕获来自麦克风的音频。请查看演示项目以获取如何执行此操作的示例。正如Larry在上面指出的那样,不要期望有很低的延迟。NAudio还具有用于混音器API的托管包装器,这应该可以让您设置麦克风音量,尽管从程序上获得正确的控件可能会有些棘手。

1

我刚刚写了一个(非常基础的)示例代码,演示了如何使用SlimDX 从麦克风捕获声音。如果你还在寻找答案,希望它能帮到你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接