当前位置:  开发笔记 > 开发工具 > 正文

给定一个音频流,找到一个门猛击(声压级计算?)

如何解决《给定一个音频流,找到一个门猛击(声压级计算?)》经验,为你挑选了4个好方法。

与拍手探测器不同("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肯定符合要求.

-亚当



1> coobird..:

查看源音频文件的屏幕截图,检测声级变化的一种简单方法是对样本进行数值积分,以找出特定时间波的"能量".

一个粗略的算法是:

    将样品分成几个部分

    计算每个部分的能量

    取上一个窗口和当前窗口之间的能量比

    如果比率超过某个阈值,请确定突然发出巨响.

伪代码

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位采样.

优点缺点

这种方法的优点是如果源音频作为整数馈入,则可以用简单的整数运算来执行处理.如前所述,捕获是实时处理将有延迟,具体取决于集成的部分的大小.

我可以想到这个方法有几个问题:

    如果背景噪声太大,则背景噪声与门关闭之间的能量差异将不容易区分,并且可能无法检测到门关闭.

    任何突然的噪音,如拍手,都可以视为门关闭.

也许,结合其他答案中的建议,例如尝试使用傅立叶分析来分析门关闭的频率特征,这将需要更多处理,但会使其不易出错.

在找到解决这个问题的方法之前,可能需要进行一些实验.



2> James Cacces..:

您应该点击车内的车门关闭开关.尝试用声音分析来做这件事是过度工程.

关于不同的信号处理方法有很多建议,但实际上,当你了解检测理论时,构建一个嵌入式信号处理板,学习你选择的芯片的处理架构,尝试算法,调试它,然后根据你想要使用它的汽车进行调整(然后为其他所有汽车重新调整并重新调试),你会希望你只需要将汽车内部的磁簧开关贴上,然后用磁铁将磁铁拧到磁铁上.门.

并不是说为dsp专家解决这个问题并不是一个有趣的问题,但从你问这个问题的方式来看,很明显声音处理不是你想要的路线.让它正常工作只会是一场噩梦.

此外,拍板只是一个送入阈值检测器的高通滤波器.(加上一个计时器,以确保2个拍手足够快一起)


对不起,如果我像屁股一样离开,但你似乎对信号处理很陌生.如果您想要玩或学习,我不想让您失望,但如果您想在合理的时间内对门关闭检测做出真正的解决方案,音频信号处理可能是最困难的路线.

3> Drew Hall..:

在雷达领域有很多关于这个问题的相关文献(称为检测理论).

您可以查看"单元平均CFAR"(恒定误报率)检测.维基百科在这里有一点点.你的想法与此非常相似,它应该有效!:)

祝好运!



4> ccook..:

我首先看一下光谱.我在你给出的两个音频文件上做了这个,你似乎可以使用一些相似之处.例如,两者之间的主要差异似乎是大约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))

推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有