中的一系列模式(這是在Python和代碼將是巨大的,但我的算法感興趣。)找到一個數據流
我監控的音頻流(PyAudio)並尋找一系列5個流行音樂(查看底部的可視化)。我正在閱讀()流,並獲取剛纔讀取的塊的RMS值(類似於this question)。我的問題是,我不是在尋找一個單一的事件,而是一系列具有某些特徵但並不像我想要的布爾值的事件(彈出)。檢測這五種流行音樂最直接的方法是什麼?
的RMS功能給了我這樣的流:
0.000580998485254, 0.00045098391298, 0.00751436443973, 0.002733730043, 0.00160775708652, 0.000847808804511
它看起來有點更加有用的,如果我圓(類似的流)爲您提供:
0.001, 0.001, 0.018, 0.007, 0.003, 0.001, 0.001
你可以看到彈出在項目3中,大概是因爲它在項目4中靜止下來,並且可能尾部在項目5的一小部分中。
我想檢測連續中的5個。
我的天真做法是: a)定義什麼是彈出:塊的RMS超過.002。至少2塊但不超過4塊。沉默開始,沉默結束。另外,我很想定義什麼是沉默(忽略不是很響,但不是很沉默的塊,但我不確定這是否更有意義,然後考慮'流行'是布爾值)。
b)然後有一個狀態機跟蹤一堆變量,並有一堆if語句。像:
while True:
is_pop = isRMSAmplitudeLoudEnoughToBeAPop(stream.read())
if is_pop:
if state == 'pop':
#continuation of a pop (or maybe this continuation means
#that it's too long to be a pop
if num_pop_blocks <= MAX_POP_RECORDS:
num_pop_blocks += 1
else:
# too long to be a pop
state = 'waiting'
num_sequential_pops = 0
else if state == 'silence':
#possible beginning of a pop
state = 'pop'
num_pop_blocks += 1
num_silence_blocks = 0
else:
#silence
if state = 'pop':
#we just transitioned from pop to silence
num_sequential_pops += 1
if num_sequential_pops == 5:
# we did it
state = 'waiting'
num_sequential_pops = 0
num_silence_blocks = 0
fivePopsCallback()
else if state = 'silence':
if num_silence_blocks >= MAX_SILENCE_BLOCKS:
#now we're just waiting
state = 'waiting'
num_silence_blocks = 0
num_sequential_pops = 0
該代碼並不完全(可能有一個或兩個錯誤),但說明了我的思路。這當然比我想要的要複雜,這就是爲什麼我要求提出建議。
在任何情況下,我是否仍然保持流行已經持續了多長時間的狀態(即使使用SMA,如果持續3秒,它也不是流行音樂)。爲了衡量流行音樂播放了多長時間,我需要跟蹤它自啓動以來的幀數,並且如果我們目前處於流行或非流行狀態?還有過去的流行#或者,SMA會以我沒有看到的方式解決其中的一些問題? –
如果沒有數據及其轉換的觀點,我很難走得更遠。如果是我,我會得到你的輸入數據樣本,其中有好幾個好奇的現象;編寫一個函數來繪製數據;應用不同的平滑,流行檢測算法等;在新圖上顯示原始+平滑+彈出檢測+行中五行檢測;然後調整,直到它適合你。一旦完成,然後運行一個新的,更大的樣本數據,並確保它可以正常使用它:-) – Paddy3118
我的困難不是轉換(RMS或簡單的移動平均值或任何似乎足夠這個用例),但實際檢測到一個pop,然後連續檢測多個pop。我會發布我的代碼。感謝您的回答。 –