中的一系列模式(这是在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。我会发布我的代码。感谢您的回答。 –