曲のテンポ/BPM をプログラムで決定するにはどうすればよいですか? どのようなアルゴリズムが一般的に使用され、どのような考慮事項が必要ですか?
10 に答える
これは、単一の StackOverflow 投稿で説明するのは困難です。一般に、最も単純なビート検出アルゴリズムは、音のエネルギーのピークを検出することで機能します。これは簡単に検出できます。より高度な方法では、くし形フィルターやその他の統計/波形方法を使用します。コード サンプルを含む詳細な説明については、この GameDev の記事を参照してください。
検索するキーワードは「ビート検出」「ビートトラッキング」「音楽情報検索」です。ここには多くの情報があります: http://www.music-ir.org/
MIREX と呼ばれる (おそらく) 毎年開催されるコンテストでは、さまざまなアルゴリズムがビート検出のパフォーマンスについてテストされます。
http://nema.lis.illinois.edu/nema_out/mirex2010/results/abt/mck/
これにより、テストするアルゴリズムのリストが表示されます。
古典的なアルゴリズムはBeatroot (google it) です。これは素晴らしく、理解しやすいものです。それはこのように動作します:
- 音楽を短時間FFTしてソノグラムを取得します。
- 各時間ステップのすべての周波数でのマグニチュードの増加を合計します (減少は無視します)。これにより、「スペクトル フラックス」と呼ばれる 1D 時変関数が得られます。
- 古いピーク検出アルゴリズムを使用してピークを見つけます。これらは「オンセット」と呼ばれ、音楽の音の始まり (音符の始まり、ドラム ヒットなど) に対応します。
- 開始間隔 (IOI) のヒストグラムを作成します。これは、可能性の高いテンポを見つけるために使用できます。
- ビート追跡結果の「エージェント」または「仮説」のセットを初期化します。これらのエージェントにオンセットを順番に 1 つずつフィードします。各エージェントは、ビートでもあるオンセットのリストと現在のテンポ推定値を追跡します。エージェントは、オンセットが最後に追跡されたビートとテンポに密接に適合する場合はオンセットを受け入れ、大きく異なる場合は無視するか、その間にある場合は新しいエージェントを生成することができます。すべてのビートがオンセットを必要とするわけではありません - エージェントは補間できます。
- 各エージェントには、その仮説がどれだけ整っているかに応じてスコアが与えられます。すべてのビートの開始が大きい場合、より高いスコアが得られます。それらがすべて規則的であれば、より高いスコアが得られます。
- 最高得点のエージェントが答えです。
私の経験では、このアルゴリズムの欠点:
- ピーク検出はかなりアドホックで、しきい値パラメーターなどに敏感です。
- 一部の音楽では、ビートに明らかなオンセットがありません。明らかに、それらでは機能しません。
- 特にライブ トラッキングでは、60bpm と 120bpm の問題を解決する方法がわかりません。
- 1D スペクトル フラックスのみを使用すると、多くの情報が破棄されます。いくつかの帯域制限されたスペクトル フラックス (およびドラム用の 1 つの広帯域スペクトル フラックス) を用意することで、より良い結果が得られると思います。
これは、このアルゴリズムのライブ バージョンのデモで、スペクトル フラックス (下部の黒い線) とオンセット (緑の円) を示しています。緑色の円のみからビートが抽出されていることは考慮に値します。オンセットをクリックと同じように再生しましたが、正直なところ、ビートからビートを聞くことができなかったと思います。そのため、ある意味で、このアルゴリズムはビート検出において人々よりも優れています。ただし、そのような低次元信号への削減はその弱いステップだと思います。
腹立たしいことに、数年前にビート検出用のアルゴリズムとコードがたくさんある非常に優れたサイトを見つけました。しかし、私はそれを再発見することに完全に失敗しました。
編集:見つけた!
ここにあなたが始めるためのいくつかの素晴らしいリンクがあります:
ビート抽出には、音楽における認知メトリック構造の識別が含まれます。非常に多くの場合、これらは物理的な音のエネルギーに対応していません。たとえば、ほとんどの音楽にはシンコペーションのレベルがあり、これは、私たちが知覚する「足を叩く」ビートが物理的な音の存在に対応していないことを意味します。これは、これが物理的な音の検出であるオンセット検出とはまったく異なる分野であり、異なる方法で実行されることを意味します。
オンセットとビート抽出ツールの両方を提供するプレーンな C ライブラリであるAubioライブラリを試すことができます。
オンラインのEchonest APIもありますが、これには MP3 を Web サイトにアップロードして XML を取得する必要があるため、あまり適していない可能性があります。
編集:私は昨夜これに出くわしました.非常に有望な C/C++ ライブラリですが、私自身は使用していません. Vamp プラグイン
あなたが興味を持っている研究の一般的な分野は、音楽情報検索と呼ばれます
これを行うさまざまなアルゴリズムがありますが、それらはすべて基本的に ONSET DETECTION を中心にしています。
オンセット検出は、イベントの開始を測定します。この場合のイベントは、演奏されているノートです。重み付きフーリエ変換 (高周波数コンテンツ) の変化を探すことができ、スペクトル コンテンツの大きな変化を探すことができます。(スペクトル差)。(さらに下を参照することをお勧めする論文がいくつかあります) オンセット検出アルゴリズムを適用すると、しきい値を使用してビートがどこにあるかを選択します。
ビートのその時間のローカリゼーションを取得したら、使用できるさまざまなアルゴリズムがあります。それをパルス列に変換し(常にゼロで、ビートが発生したときにのみ1になる信号を作成します)、それにFFTを適用すると、BAMが最大ピークでオンセットの周波数になります。
正しい方向に導くためのいくつかの論文を次に示します。
http://www.elec.qmul.ac.uk/people/juan/Documents/Bello-TSAP-2005.pdf
http://bingweb.binghamton.edu/~ahess2/Onset_Detection_Nov302011.pdf
一部の人々が議論していることの拡張は次のとおりです。
誰かが機械学習アルゴリズムの適用を検討していると述べました。基本的には、オンセット検出関数 (上記) から一連の特徴を収集し、それらをニューラル ネットワーク/ロジスティック回帰で生の信号と組み合わせて、ビートをビートにするものを学習します。
Andrew Ng 博士を調べてみてください。彼はスタンフォード大学からオンラインで機械学習の講義を無料で受けています (長々としたビデオ講義ではなく、実際にはオンライン遠隔コースがあります)。
プロジェクトで python コードとのインターフェイスを管理できる場合、Echo Nest Remix APIは python 用の非常に洗練された API です。
analysis.tempo
BPM を取得する方法があります。API ドキュメントまたはこのチュートリアルからわかるように、単純な BPM よりもはるかに多くのことができます。
フーリエ変換を実行し、パワー スペクトルのピークを見つけます。人間の聴覚の 20 Hz カットオフより下のピークを探しています。通常は 0.1 ~ 5 Hz の範囲が寛大であると思います。
役立つかもしれない SO の質問: Bpm オーディオ検出ライブラリ
また、SO に関するいくつかの「ピーク検出」の質問の 1 つを以下に示します。測定されたシグナルのピーク検出
編集:オーディオ処理を行っているわけではありません。ファイルの周波数ドメイン プロパティを探しているという事実に基づく推測にすぎません...
別の編集: mp3 のような非可逆圧縮形式は、そもそも時間ドメイン データではなくフーリエ ドメイン データを保存することに注意してください。少し賢くすることで、重い計算を省くことができます...しかし、cobbal による思慮深いコメントを参照してください。
BPM を取得するにはいくつかの方法がありますが、私が最も効果的だと思うのは「ビート スペクトル」です (ここで説明します)。このアルゴリズムは、音楽の各短いサンプルを他のすべてのサンプルと比較することにより、類似度マトリックスを計算します。類似性行列が計算されると、各時間間隔 T の各サンプル ペア {S(T);S(T+1)} 間の平均類似性を取得できます。これがビート スペクトルです。ビート スペクトルの最初の高いピークは、ほとんどの場合、ビートの持続時間です。最良の部分は、音楽構造やリズム分析なども実行できることです。
他の人は、いくつかのビート検出方法をすでに説明しています。この種のタスクのための技術とアルゴリズムを提供する利用可能なライブラリがいくつかあることを付け加えたいと思います。
Aubioはその 1 つで、定評があり、C++ ラッパーを使用して C で記述されているため、cocoa アプリケーションと簡単に統合できます (Apple のフレームワークのすべてのオーディオ機能も C/C++ で記述されています)。
私の答えを再投稿するには:それを行う簡単な方法は、ユーザーにビートに合わせてリズムでボタンをタップさせ、タップ数を時間で割ってカウントすることです。
1 秒間に約 2 回、低周波の 1 つの音が鳴るはずなので、これは 4-4 のダンス ミュージックで最も簡単だと思います。