与拍手探测器不同("Clap on!clap clap Clap off!clap clap Clap on,clap off,Clapper! clap clap ")我需要检测门何时关闭.这是一辆车,比房间或家门更容易:
听:http://ubasics.com/so/van_driver_door_closing.wav
看:
它的采样速率为16位4khz,我希望避免大量处理或存储样本.
当您在大胆或其他波形工具中查看它时,它非常独特,并且由于车辆中声压的增加而几乎总是剪辑 - 即使窗户和其他门打开时:
听:http://ubasics.com/so/van_driverdoorclosing_slidingdoorsopen_windowsopen_engineon.wav
看:
我希望有一个相对简单的算法可以读取4kHz,8位的读数,并跟踪"稳态".当算法检测到声级显着增加时,它将标记该点.
你的想法是什么?
你怎么会发现这个事件?
声压级计算的代码示例是否有帮助?
我可以减少采样频率(1kHz甚至更慢?)
更新:使用Octave(开源数值分析 - 类似于Matlab)并查看均方根是否会给我我需要的东西(这导致与SPL非常相似的东西)
Update2:在简单的情况下,计算RMS可以轻松地关闭门:
现在我只需要看看困难的情况(收音机,高温/高空等).CFAR看起来非常有趣 - 我知道我将不得不使用自适应算法,CFAR肯定符合要求.
-亚当
查看源音频文件的屏幕截图,检测声级变化的一种简单方法是对样本进行数值积分,以找出特定时间波的"能量".
一个粗略的算法是:
将样品分成几个部分
计算每个部分的能量
取上一个窗口和当前窗口之间的能量比
如果比率超过某个阈值,请确定突然发出巨响.
伪代码
samples = load_audio_samples() // Array containing audio samples WINDOW_SIZE = 1000 // Sample window of 1000 samples (example) for (i = 0; i < samples.length; i += WINDOW_SIZE): // Perform a numerical integration of the current window using simple // addition of current sample to a sum. for (j = 0; j < WINDOW_SIZE; j++): energy += samples[i+j] // Take ratio of energies of last window and current window, and see // if there is a big difference in the energies. If so, there is a // sudden loud noise. if (energy / last_energy > THRESHOLD): sudden_sound_detected() last_energy = energy energy = 0;
我应该添加一个我没有试过的免责声明.
应该可以在不首先记录样本的情况下执行这种方式.只要存在一定长度的缓冲(WINDOW_SIZE
在该示例中),就可以执行数值积分来计算声音部分的能量.然而,这确实意味着处理将会有延迟,这取决于长度WINDOW_SIZE
.确定一段声音的良好长度是另一个问题.
如何分成章节
在第一个音频文件中,似乎门关闭声音的持续时间是0.25秒,因此用于数值积分的窗口应该最多可以是其中的一半,或者甚至更像是十分之一,因此,即使窗口在静音部分和噪声部分之间重叠,也可以注意到静音和突然的声音.
例如,如果积分窗口是0.5秒,并且第一个窗口覆盖0.25秒的静音和0.25秒的关门,第二个窗口覆盖0.25秒的关门和0.25秒的静音,可能看起来声音的两个部分具有相同的噪声水平,因此不会触发声音检测.我想有一个短窗可以缓解这个问题.
然而,具有太短的窗口将意味着声音的上升可能不完全适合一个窗口,并且可能暗示相邻部分之间的能量差异很小,这可能导致声音被遗漏.
我相信,WINDOW_SIZE
并且THRESHOLD
必须根据经验确定将被检测到的声音.
为了确定该算法需要保留在内存中的样本数量,假设WINDOW_SIZE
是门关闭声音的1/10,大约是0.025秒.采样率为4 kHz,即100个样本.这似乎不是太多的内存要求.使用200字节的16位采样.
优点缺点
这种方法的优点是如果源音频作为整数馈入,则可以用简单的整数运算来执行处理.如前所述,捕获是实时处理将有延迟,具体取决于集成的部分的大小.
我可以想到这个方法有几个问题:
如果背景噪声太大,则背景噪声与门关闭之间的能量差异将不容易区分,并且可能无法检测到门关闭.
任何突然的噪音,如拍手,都可以视为门关闭.
也许,结合其他答案中的建议,例如尝试使用傅立叶分析来分析门关闭的频率特征,这将需要更多处理,但会使其不易出错.
在找到解决这个问题的方法之前,可能需要进行一些实验.
您应该点击车内的车门关闭开关.尝试用声音分析来做这件事是过度工程.
关于不同的信号处理方法有很多建议,但实际上,当你了解检测理论时,构建一个嵌入式信号处理板,学习你选择的芯片的处理架构,尝试算法,调试它,然后根据你想要使用它的汽车进行调整(然后为其他所有汽车重新调整并重新调试),你会希望你只需要将汽车内部的磁簧开关贴上,然后用磁铁将磁铁拧到磁铁上.门.
并不是说为dsp专家解决这个问题并不是一个有趣的问题,但从你问这个问题的方式来看,很明显声音处理不是你想要的路线.让它正常工作只会是一场噩梦.
此外,拍板只是一个送入阈值检测器的高通滤波器.(加上一个计时器,以确保2个拍手足够快一起)
在雷达领域有很多关于这个问题的相关文献(称为检测理论).
您可以查看"单元平均CFAR"(恒定误报率)检测.维基百科在这里有一点点.你的想法与此非常相似,它应该有效!:)
祝好运!
我首先看一下光谱.我在你给出的两个音频文件上做了这个,你似乎可以使用一些相似之处.例如,两者之间的主要差异似乎是大约40-50Hz.我的.02.
UPDATE
发布此内容后,我有了另一个想法.如果可以,请在设备上添加加速度计.然后关联振动和声学信号.这应该有助于跨车门检测.我认为它应该是相关的,因为声音是振动驱动的,例如,立体声不是.我有一个装置能够用挡风玻璃支架(吸盘)检测我的发动机转速,所以灵敏度可能就在那里.(我没有做出任何承诺!)
(来源:charlesrcook.com)
%% Test Script (Matlab) clear hold all %keep plots open dt=.001 %% Van driver door data = wavread('van_driver_door_closing.wav'); %Frequency analysis NFFT = 2^nextpow2(length(data)); Y = fft(data(:,2), NFFT)/length(data); freq = (1/dt)/2*linspace(0,1,NFFT/2); spectral = [freq' 2*abs(Y(1:NFFT/2))]; plot(spectral(:,1),spectral(:,2)) %% Repeat for van sliding door data = wavread('van_driverdoorclosing.wav'); %Frequency analysis NFFT = 2^nextpow2(length(data)); Y = fft(data(:,2), NFFT)/length(data); freq = (1/dt)/2*linspace(0,1,NFFT/2); spectral = [freq' 2*abs(Y(1:NFFT/2))]; plot(spectral(:,1),spectral(:,2))