単純な C# アプリケーションを作成して、ライン入力オーディオを監視し、現在の (ローリング平均) ビート/分を取得したいと考えています。
この gamedev articleを見たことがありますが、それはまったく役に立ちませんでした。私は彼がやっていることを実行しようとしましたが、うまくいきませんでした。
多くのDJソフトウェアがそれを行っているので、これにはたくさんの解決策が必要であることは知っていますが、オープンソースのライブラリや自分でそれを行うための指示を見つけることができません.
単純な C# アプリケーションを作成して、ライン入力オーディオを監視し、現在の (ローリング平均) ビート/分を取得したいと考えています。
この gamedev articleを見たことがありますが、それはまったく役に立ちませんでした。私は彼がやっていることを実行しようとしましたが、うまくいきませんでした。
多くのDJソフトウェアがそれを行っているので、これにはたくさんの解決策が必要であることは知っていますが、オープンソースのライブラリや自分でそれを行うための指示を見つけることができません.
スライディングウィンドウを使用してパワースペクトルを計算します。FFT:1024サンプルを取得します。
double[] signal = stream.Take(1024);
それをFFTアルゴリズムにフィードします。
double[] real = new double[signal.Length];
double[] imag = new double[signal.Length);
FFT(signal, out real, out imag);
実数部と虚数部が得られます。虚数部を捨てないでください。虚数と同じことを実数部に行います。虚数部が実数部とpi/2位相がずれていることは事実ですが、それでもスペクトル情報の50%が含まれています。
編集:
振幅ではなく電力を計算して、音量が大きい場合は数値を大きくし、音量が小さい場合は数値をゼロに近づけます。
for (i=0; i < real.Length; i++) real[i] = real[i] * real[i];
架空の部分も同様です。
for (i=0; i < imag.Length; i++) imag[i] = imag[i] * imag[i];
これで、最後の1024サンプルのパワースペクトルが得られました。ここで、スペクトルの最初の部分は低周波数であり、スペクトルの最後の部分は高周波数です。
ポピュラー音楽でBPMを見つけたい場合は、おそらく低音に焦点を当てる必要があります。パワースペクトルの下部を合計することで、低音の強さを拾うことができます。使用する数値は、サンプリング周波数によって異なります。
double bassIntensity = 0;
for (i=8; i < 96; i++) bassIntensity += real[i];
ここでもう一度同じことを行いますが、新しいスペクトルを計算する前にウィンドウを256サンプル移動します。これで、256サンプルごとにbassIntensityを計算することになります。
これは、BPM分析に適した入力です。低音が静かなときはビートがなく、音量が大きいときはビートがあります。
幸運を!
音楽から DDR ダンス ステップを手続き的に生成する Dancing Monkeys という優れたプロジェクトがあります。それが行うことの大部分は(必然的に非常に正確な)ビート分析に基づいており、彼らのプロジェクトペーパーは、さまざまなビート検出アルゴリズムとタスクへの適合性を説明する詳細に記載されています。これらには、各アルゴリズムの元の論文への参照が含まれています。また、ソリューションの matlab コードも公開しています。それらの間で必要なものを見つけることができると確信しています。
ここですべて入手できます: http://monket.net/dancing-monkeys-v2/Main_Page
これを実装する方法の手がかりがあるわけではありませんが、オーディオエンジニアリングの観点からは、最初にフィルタリングする必要があります. バスドラムのヒットが最初にチェックされます。約 200Hz 未満のローパス フィルターを使用すると、バス ドラムのイメージがかなり明確になります。ゲートは、ハーモニクスが低い他の楽器からの混乱をクリーンアップするためにも必要になる場合があります。
次にチェックするのはスネアヒットです。これをEQする必要があります。スネアからの「クラック」はメモリから約 1.5kHz ですが、これを確実にゲートする必要があります。
次の課題は、ファンキーなビートのアルゴリズムを開発することです。どのようにプログラムでビート 1 を見つけますか? 以前のビートを追跡して、何かに一致するパターンを使用すると思います。したがって、ビートを正確に見つけるには、おそらく数小節が必要になるでしょう。次に、4/4、3/4、6/8 などのタイミングの問題があります。うわー、これを正確に行うために何が必要か想像できません! オーディオ ハードウェア/ソフトウェア企業にとっては、多額の費用を投じる価値があると確信しています。
これは決して簡単な問題ではありません。概要のみを説明します。
あなたができることは次のようなものです:
フーリエ変換は基本的に、信号に存在するすべての周波数の強度を計算する方法です。「ブロックされた」信号に対してこれを行うと、ビートの周波数が最も強くなることが期待されます。
通常、BPMに関するほとんどの情報を含む特定の周波数(低音など)に焦点を合わせるために、最初にフィルターを適用する必要があるかもしれません。
BeatsperMinuteを検出するためのかなり堅実な実装があるように見えるこのライブラリを見つけました。 https://github.com/owoudenberg/soundtouch.net
これは、かなりの数のDJプロジェクトで使用されているhttp://www.surina.net/soundtouch/index.htmlに基づいていますhttp://www.surina.net/soundtouch/applications.html
まず第一に、Hallgrim が生成しているのは、パワー スペクトル密度関数ではありません。任意の信号の統計的周期性は、自己相関関数によって引き出すことができます。自己相関信号のフーリエ変換は、パワー スペクトル密度です。0 Hz 以外の PSD の主要なピークは、信号の有効な周期性 (Hz) に対応します...
これを行う簡単な方法は、ユーザーにビートに合わせてボタンをタップさせ、タップ数を時間で割ってカウントすることです。
BASS オーディオ ライブラリと BASS.NET ラッパーをチェックすることをお勧めします。BPMCounter クラスが組み込まれています。
この特定の機能の詳細については、 http://bass.radio42.com/help/html/0833aa5a-3be9-037c-66f2-9adfd42a8512.htmを参照してください。