Delphi 带Bass.DLL的简易婴儿监视器
我正在尝试为Windows(个人使用)编写一个简单的婴儿监视器。 婴儿监护仪应仅检测麦克风的dB电平,并在一定音量下触发 经过一些研究,我找到了Bass.dll库,找到了它的函数Delphi 带Bass.DLL的简易婴儿监视器,delphi,bass,bass.dll,Delphi,Bass,Bass.dll,我正在尝试为Windows(个人使用)编写一个简单的婴儿监视器。 婴儿监护仪应仅检测麦克风的dB电平,并在一定音量下触发 经过一些研究,我找到了Bass.dll库,找到了它的函数Bass\u ChannelGetLevel,这很好,但似乎有局限性,不适合我的需要(峰值等于一个DWORD值) 在这些示例中,我发现了一个livespec示例,它“几乎”满足了我的需要。示例使用了BASS\u ChannelGetData,但我不太知道如何处理返回的数组 我希望尽可能简单:将麦克风的音量检测为dB或任何
Bass\u ChannelGetLevel
,这很好,但似乎有局限性,不适合我的需要(峰值等于一个DWORD值)
在这些示例中,我发现了一个livespec示例,它“几乎”满足了我的需要。示例使用了BASS\u ChannelGetData
,但我不太知道如何处理返回的数组
我希望尽可能简单:将麦克风的音量检测为dB或任何其他值(例如值0-MAXINT)
如何使用Bass.dll库实现这一点?Bass\u ChannelGetLevel返回上限为0dB的值(本例中返回值为32768)。如果您调整源电平(声卡设置中的麦克风电平较低),则工作正常 另一种方法是,如果您想获得无上限值,可以使用
BASS\u ChannelGetLevelEx
函数:它返回浮点级别,其中1是对应于BASS\u ChannelGetLevel的32767的最大(0dB)值,但它可以超过1来检测高于0dB的音量,这是您可能需要的
我还建议您监视一段时间的声级:仅当某个声级存在至少2-3秒时触发(这样您将排除假警报)。以下是给定输入流句柄(streamHandle)获得db声级的方法: 或者,您可以使用以下公式获得RMS(平均)峰值。要获得RMS值,必须将采样长度传入
BASS\u 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());
希望这有帮助。检查
DWORD
是一个32位无符号值。这有什么不对?您说过可以使用介于0
和MaxInt
之间的值,那么为什么不使用DWORD
?见鬼,即使它是一个8位字节
或8位短整数
,你也只需要缩放它。我不太明白您的问题。您需要找到一种方法来降低录制音量,以便能够检测峰值。如果您低声说的话,它已经达到了极限,那么它是高(DWORD)
,是最大值的两倍,所以这不是DLL的问题,这是你的音源的问题。@BenjaminWeiss如果耳语已经达到极限,那么我想你可能需要在声卡设置中调整(降低)你的麦克风音量。另外,请确保禁用声卡的麦克风自动音量调节功能(有时称为麦克风自动增益)。此功能非常有用,因此您无需一直直接对着麦克风讲话,因为如果您的嘴不直接对着麦克风,您的讲话将以较低的音量录制,因为您的嘴发出的声音是定向的。我设法使其与Ex功能一起工作。正是我要找的!非常感谢你!
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());