HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2008
1129
pennBPMの検出5解決


penn

リンク

2008/11/29(Sat) 19:00:08|NO.21135

たびたびの質問すいません

exmp3dll.asを使ったメディアプレーヤーを作っているのですが
音楽からBPM(テンポ)を検出する方法が分からなくて困っています

だれか方法が分かる方いませんか?



この記事に返信する


GENKI

リンク

2008/11/30(Sun) 00:34:48|NO.21140

音楽をFFTして結果を分析してみてください。
FFTについてはこの掲示板の過去ログに話題があがってたと思います。
解決してたかどうかまでは覚えてませんが…。



ほげ

リンク

2008/11/30(Sun) 01:31:58|NO.21142

MP3タグからBPM情報を取得するなら簡単そう
だけど音楽から検出となると・・・単純には行かないような気がする・・・!



GENKI

リンク

2008/11/30(Sun) 01:53:19|NO.21143

> MP3タグからBPM情報を取得するなら簡単そう

そんなタグを埋めこめられたんですね。
でも基本的には手動で入力しておく必要があるようです。
調べてみると自動化ツールありました。
http://www.undermountain.biz/archives/56



New Monkey

リンク

2008/11/30(Sun) 08:08:05|NO.21147

なんとなくですができました。
考え方。拍の部分は他より音圧が大きいので、時系列の音圧データから周期的に(何個かおきに)値を取り出して平均をとったとすると、取り出した値が全て拍の部分だったときに平均値は最大になる。逆の言い方をすると、時系列音圧データから色々な周期(間隔)で値を取り出しそれぞれの場合の平均値を求める。(拍と曲の開始の時間的なずれも考慮しなくてはならない。)この平均値が最大になるときの周期からBPMを算出することができる(たぶん)
音楽知識がろくにないため一部適当にごまかしましたが、K5 Auto Tempo Getterというテンポ取得ソフトの結果と比べても近い値を出します。
同じフォルダにVBMP3.dllが必要です。

#include "d3m.hsp" #uselib "vbmp3.dll" #func vbmp3_init "vbmp3_init" #func vbmp3_free "vbmp3_free" #func vbmp3_open "vbmp3_open" sptr, sptr #func vbmp3_close "vbmp3_close" #func vbmp3_play "vbmp3_play" #func vbmp3_restart "vbmp3_restart" #func vbmp3_pause "vbmp3_pause" #func vbmp3_getSpectrum "vbmp3_getSpectrum" sptr, sptr #const SAMPLENUM 1000 //判定に使うサンプル数 #const LOW 100 //BPM検出範囲 #const HIGH 199 #const BEAT 2 //拍数?(よくわからないが2にすると合うみたい) #const AMP 2 //表示倍率 screen 0, SAMPLENUM, 250 onexit *Exit onkey *Analyze dim specL, 256 dim specR, 256 sdim InputInfo, 272 vbmp3_init dialog "", 16, "mp3;*.wav" if stat=0 { end } vbmp3_open refstr, varptr(InputInfo) vbmp3_play vbmp3_pause *Analyze dim data, SAMPLENUM color : boxf color 64, 64, 64 : line ginfo_winx, ginfo_winy-20, 0, ginfo_winy-20 color 255, 0, 0 pos 0 vbmp3_restart time = d3timer() repeat SAMPLENUM i = cnt vbmp3_getSpectrum varptr(specL), varptr(specR) repeat 256 data(i) += (specL(cnt)+specR(cnt))/2 loop data(i) /= 256 //音圧 redraw 0 line i, ginfo_winy-20-data(i)*AMP redraw 1 wait 1 loop time = d3timer()-time //全サンプルの時間(ms) vbmp3_pause dt = double(time)/SAMPLENUM //1サンプルの時間(ms) i1 = 60.0*1000/HIGH*BEAT/dt //検出BPM範囲をサンプル数に換算 i2 = 60.0*1000/LOW*BEAT/dt maxval = 0 repeat i2-i1, i1 i = cnt repeat i //全てのずれのパターンを試す j = cnt val = 0 k = 0 repeat SAMPLENUM if (cnt\i=0)&(cnt+j<SAMPLENUM) { val += data(cnt+j) k++ } loop val = val/k if val>maxval { maxval = val : interval = i : shift = j } loop loop color 0, 255, 0 if interval=0 { title "failed" : stop } repeat SAMPLENUM/interval+1 line interval*cnt+shift, 0, interval*cnt+shift, ginfo_winy loop color 255, 255, 255 : pos 0, 0 title ""+strf("%.1f", (double(SAMPLENUM)/interval)/(double(time)/1000/60)*BEAT) + "BPM" stop *Exit vbmp3_close vbmp3_free end



penn

リンク

2008/12/1(Mon) 20:29:12|NO.21174

NewMonkeyさんありがとうございます!!

その考え方とスクリプト 使わせていただきます

いろいろ考えてくれた皆様ありがとうございました



ONION software Copyright 1997-2023(c) All rights reserved.