2014年12月5日金曜日

バンドパスフィルタをHW化すれば8bitマイコンでもいけそう。



しなぷす さんに教えて貰ったMSGEQ7というバンドパスフィルタを使えば前回いっていたリズム検知が簡単に実装できそうなのでためしてみた。(実チップでの処理ではなくデータシートから読み取ったインチキシミュレータです)


https://www.switch-science.com/catalog/585/


初音ミクの「イノセンス」のサビ部分(83秒付近)を処理するとこんな感じ、サビに入る部分はリズムがちょっとつぶれてるけど、それ以外はリズムが取れてる。リズムで電飾光らせるぐらいなら、十分だと思う。


f:id:akira_you:20141205061246p:image


横軸の単位は(秒)です。


赤線が積を取った信号(ちょっと正規化してるけど)。緑線はそれにさらにローパス(立ち上がりのみローパスなし)フィルタをかけたもの。


緑と赤が共にぎゅんと上がって、その後離れる点をビート点とすればよさそう。





マイコン側の処理は以下のように5チャンネル分の積をとって正規化するのと、ローパスのみ。これを100Hz周期で繰り返す事を想定してます。100Hz周期で取ってくるのでMSGEQ7の63Hzや130Hzバンドは信用できない状況になっているのでとりあえずデータを捨てています。



class LPF
def initialize
@rate=0.9
@outValue=0.0
end
attr_accessor :rate,:outValue;
def putp(v)
@outValue=v if(@outValue<v)
@outValue=(1.0-@rate)*v+@rate*@outValue;
return @outValue
end
end
#
#(略)以下メインループ
#
#ここでretにMSG7EQの出力が入る
m=1.0
a=0.0
ret[-5..-1].each { |r| m *= r ;a+= r} #低周波はあまり信用できないはず
v=m
v=m/(a**2 + 1.0E-100) #綺麗に正規化まではしない。音量と相関値との中間ぐらいの特徴量
r=[v,llpf.putp(v)] #ここで出力信号が入る
puts r.join("\t")






0 件のコメント:

コメントを投稿