查看源音頻文件的截圖,檢測聲音級別變化的一種簡單方法是做樣本的numerical integration以查明特定時間波的「能量」。
粗略算法將是:
- 除以樣品分成幾塊
- 計算每個節
- 的能量取前一個窗口和當前窗口間的能量的比率
- 如果比率超過某個閾值,請確定存在突然的巨大噪音。
僞
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位採樣。
優點/缺點
這種方法的優點是如果源的音頻被饋送在作爲整數可以用簡單的整數運算來執行的處理。正如已經提到的那樣,捕獲是實時處理將會有一個延遲,這取決於整合的部分的大小。
有幾個是我能想到的這個方法的問題:
- 如果背景噪音過大,背景噪聲和關門之間的能量差也不會很容易區分,並且可能無法檢測到關門。
- 任何突然的噪音,如拍手,都可以視爲門關閉。
也許,建議在其他的答案,比如試圖分析利用傅立葉分析關門,這將需要更多的處理,但會使其不太容易出錯的頻率特徵相結合。
在找到解決此問題的方法之前,可能需要進行一些實驗。
加速度計是一個選項嗎? – ccook 2009-02-01 06:51:18
我在主板上包含一個三軸加速度計。順便提一句,它還包括壓力傳感器,光線傳感器,門開關檢測,GPS和相機。雖然這些選項可用,但理想情況下,設計只需要麥克風進行門鎖感應。 – 2009-02-01 06:54:51
只是一個隨機的想法 - 如果它在關閉時幾乎總是剪輯 - 爲什麼不只是檢測剪輯? – aronchick 2009-05-07 18:18:31