4

我正在尝试为 Windows(个人使用)编写一个简单的 Babymonitor。babymonitor 应该只检测麦克风的 dB 电平并以一定的音量触发。

经过一番研究,我找到了 Bass.dll 库并发现了它的功能BASS_ChannelGetLevel,它很棒,但似乎有局限性并且不符合我的需求(峰值等于 DWORD 值)。

在示例中,我发现了一个“几乎”我需要的 livespec 示例。该示例使用BASS_ChannelGetData,但我不太清楚如何处理返回的数组...

我想让它尽可能简单:检测麦克风的音量为 dB 或任何其他值(例如值 0-MAXINT)。

Bass.dll 库如何做到这一点?

4

2 回答 2

3

返回上限为 0dB的BASS_ChannelGetLevel值(在这种情况下,返回值为 32768)。如果您调整源电平(声卡设置中的较低麦克风电平),那么它会正常工作。

另一种方法,如果你想获得无上限的值是使用该BASS_ChannelGetLevelEx函数:它返回浮点级别,其中 1 是对应于 BASS_ChannelGetLevel 的 32767 的最大值 (0dB) 值,但它可以超过 1 来检测高于 0dB 的声级,即你可能需要什么。

我还建议您监视一段时间的声级:仅当某个级别至少存在 2-3 秒时才触发(这样您将排除误报)。

于 2016-10-31T14:33:13.140 回答
1

以下是在给定输入流句柄 (streamHandle) 的情况下获取 db 级别的方法:

var peak = (double)Bass.BASS_ChannelGetLevel(streamHandle);
var decibels = 20 * Math.Log10(peak / Int32.MaxValue);

或者,您可以使用以下方法获取 RMS(平均)峰值。要获得 RMS 值,您必须将样本长度传入BASS_ChannelGetLevel. 我在这里使用 20 毫秒,但您可以使用该值来查看哪个最适合您的需求。

var decibels = 0m;
var channelCount = 2; //Assuming two channels
var sampleLengthMS = 20f;
var rmsLevels = new float[channelCount];
var rmsObtained = Bass.BASS_ChannelGetLevel(streamHandle, rmsLevels, sampleLengthMS / 1000f, BASSLevel.BASS_LEVEL_RMS);

if (rmsObtained)
     decibels = 20*Math.Log10(rmsLevels[0]);   //using first channel (index 0) but you can get both if needed.
else
     Console.WriteLine(Bass.BASS_ErrorGetCode());

希望这可以帮助。

于 2016-12-13T23:19:39.640 回答