2016-10-30 13 views
4

나는 Windows (개인 사용)를위한 간단한 Babymonitor를 프로그램하는 것을 시도하고있다. babymonitor는 마이크의 dB 레벨을 감지하고 특정 볼륨에서 트리거해야합니다.Bass.DLL을 가진 간단한 Babymonitor

일부 연구를 한 후에 Bass.dll 라이브러리를 발견하여 기능이 BASS_ChannelGetLevel 인 것을 보았습니다.이 기능은 훌륭하지만 제한 사항이있는 것으로 보이고 (Peak는 DWORD 값과 같음) 맞지 않습니다.

예에서 필자는 필자가 필요로하는 "거의"인 livespec 예제를 발견했습니다. 이 예제에서는 BASS_ChannelGetData을 사용하지만 반환 된 배열을 처리하는 방법을 잘 모릅니다 ...

가능한 한 간단하게 유지하고 싶습니다 : 마이크에서 볼륨을 dB 또는 다른 값으로 검색합니다 (예 : value 0-MAXINT).

Bass.dll 라이브러리로 어떻게이 작업을 수행 할 수 있습니까?

+2

[this] (http://stackoverflow.com/questions/5951819/how-to-listen-to-microphone-and-detect-sound-loudness-in-delphi-7)을 확인하십시오. – aring

+0

확인했습니다. 그러나 반환 값은 DWORD로 제한됩니다 ... –

+4

'DWORD'는 32 비트 부호없는 값입니다. 그게 뭐가 잘못 됐니? 당신은'0'과'MaxInt' 사이의 값으로 작업 할 수 있다고 말했습니까? 그렇다면 왜 'DWORD'가 아니겠습니까? 8 비트 'Byte'또는 8 비트 'Shortint'라고해도, 크기를 조정하면됩니다. 나는 너의 문제를 정말로 보지 못했다. –

답변

3

BASS_ChannelGetLevel은 0dB로 제한된 값을 반환합니다 (이 경우 반환 값은 32768입니다). 소스 레벨을 조정하면 (사운드 카드 설정에서 마이크 레벨이 낮아짐) 잘 작동합니다. 당신이 상한선 값을 얻으려면

또 다른 방법은, 대신 BASS_ChannelGetLevelEx 기능을 사용하는 것입니다 : 그것은 부동 소수점 수준을 반환 경우 1 BASS_ChannelGetLevel의 32767에 해당하는 최대 (0dB) 값이지만, 소리를 감지하는 일을 초과 할 수 당신이 필요로 할지도 모르는 0dB 이상의 레벨.

잠시 동안 사운드 레벨을 모니터링하는 것이 좋습니다. 적어도 2-3 초 동안 특정 레벨이 존재하는 경우에만 트리거하십시오 (이 방법은 잘못된 알람을 제외시킵니다).

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

다른 방법으로,이 (가) RMS (평균) 피크를 얻을 수를 사용할 수 있습니다 : 여기

+0

Ex 함수로 작동하도록 관리했습니다. 정확히 내가 무엇을 찾고 있었는지! 고마워요! –

1

는 입력 스트림 핸들 (streamHandle)를 주어진 데시벨 수준을 얻는 방법이다. 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()); 

희망이 있습니다.