带有 Bass.DLL 的简单婴儿监视器
Simple Babymonitor with Bass.DLL
我正在尝试为 Windows(个人使用)编写一个简单的 Babymonitor。
babymonitor 应该只检测麦克风的 dB 电平并在一定音量时触发。
经过一些研究,我找到了 Bass.dll 库并发现了它的函数 BASS_ChannelGetLevel
,这很好,但似乎有局限性并且不符合我的需要(Peak 等于一个 DWORD值)。
在示例中,我找到了一个 livespec 示例,它是 "almost" 我需要的。该示例使用 BASS_ChannelGetData
,但我不太清楚如何处理返回的数组...
我想让它尽可能简单:检测麦克风的音量为 dB 或任何其他值(例如值 0-MAXINT)。
如何使用 Bass.dll 库完成此操作?
BASS_ChannelGetLevel
return 上限为 0dB 的值(在这种情况下,return 值为 32768)。如果您调整源级别(在声卡设置中降低麦克风级别),那么它将正常工作。
另一种方法,如果你想获得无上限值,是使用 BASS_ChannelGetLevelEx
函数代替:它 returns 浮点级别,其中 1 是最大 (0dB) 值,对应于 BASS_ChannelGetLevel的 32767,但它可以超过 1 以检测高于 0dB 的声级,这正是您可能需要的。
我还建议你监测一段时间的声级:只有当某个声级存在至少 2-3 秒时才触发(这样你就可以排除误报)。
以下是在给定输入流句柄 (streamHandle) 的情况下获取数据库级别的方法:
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());
希望对您有所帮助。
我正在尝试为 Windows(个人使用)编写一个简单的 Babymonitor。 babymonitor 应该只检测麦克风的 dB 电平并在一定音量时触发。
经过一些研究,我找到了 Bass.dll 库并发现了它的函数 BASS_ChannelGetLevel
,这很好,但似乎有局限性并且不符合我的需要(Peak 等于一个 DWORD值)。
在示例中,我找到了一个 livespec 示例,它是 "almost" 我需要的。该示例使用 BASS_ChannelGetData
,但我不太清楚如何处理返回的数组...
我想让它尽可能简单:检测麦克风的音量为 dB 或任何其他值(例如值 0-MAXINT)。
如何使用 Bass.dll 库完成此操作?
BASS_ChannelGetLevel
return 上限为 0dB 的值(在这种情况下,return 值为 32768)。如果您调整源级别(在声卡设置中降低麦克风级别),那么它将正常工作。
另一种方法,如果你想获得无上限值,是使用 BASS_ChannelGetLevelEx
函数代替:它 returns 浮点级别,其中 1 是最大 (0dB) 值,对应于 BASS_ChannelGetLevel的 32767,但它可以超过 1 以检测高于 0dB 的声级,这正是您可能需要的。
我还建议你监测一段时间的声级:只有当某个声级存在至少 2-3 秒时才触发(这样你就可以排除误报)。
以下是在给定输入流句柄 (streamHandle) 的情况下获取数据库级别的方法:
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());
希望对您有所帮助。