web-dev-qa-db-ja.com

リアルタイムオーディオ入力からの毎分ビート

簡単なC#アプリケーションを作成して、ラインインオーディオを監視し、1分あたりの現在の(ローリング平均)ビートを取得したいと思います。

私は このgamedevの記事 を見てきましたが、それはまったく役に立ちませんでした。私は通り抜けて、彼がやっていたことを実装しようとしましたが、それはうまくいきませんでした。

多くのDJソフトウェアがこれを行うため、これには多くの解決策が必要であることはわかっていますが、オープンソースのライブラリを見つけたり、自分でそれを実行するための手順を見つけることができません。

43
Karl

スライディングウィンドウ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);

あなたは実部と虚部を得るでしょう。虚数部を捨てないでください。虚数部と同じように実際の部分を実行します。虚数部が実数とπ/ 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分析に適した入力です。低音が静かなときはビートがなく、大音量のときはビートがあります。

幸運を!

26
Hallgrim

音楽からDDRダンスのステップを手続き的に生成するDancing Monkeysと呼ばれる優れたプロジェクトがあります。それが行うことの大部分は(必然的に非常に正確な)ビート分析に基づいており、彼らのプロジェクトペーパーでは、さまざまなビート検出アルゴリズムとそのタスクへの適合性について詳しく説明しています。これらには、各アルゴリズムの元の論文への参照が含まれています。彼らはまた、ソリューションのmatlabコードを公開しました。それらの間にあなたが必要なものを見つけることができると私は確信しています。

それはすべてここで利用できます: http://monket.net/dancing-monkeys-v2/Main_Page

15
Nick Johnson

これを実装する手がかりがあるわけではありませんが、オーディオエンジニアリングの観点からは、最初にフィルタリングする必要があります。バスドラムのヒットが最初にチェックされます。約200Hz未満のローパスフィルターを使用すると、バスドラムのかなりはっきりした画像が得られます。ゲートは、他の楽器からのクラッタをハーモニクスが低い状態でクリーンアップするためにも必要になる場合があります。

次にチェックするのはスネアヒットです。これをEQする必要があります。スネアからの「クラック」はメモリから約1.5kHzですが、これを確実にゲートする必要があります。

次の課題は、ファンキーなビートのアルゴリズムを理解することです。プログラムでビート1をどのように見つけますか?以前のビートを追跡し、何かに一致するパターンを使用すると思います。したがって、ビートを正確に見つけるには、おそらくいくつかの小節が必要になります。それから、4/4、3/4、6/8のようなタイミングの問題があります。オーディオハードウェア/ソフトウェア会社にとっては、かなりのお金の価値があると確信しています。

8
Dan Harper

これは決して簡単な問題ではありません。概要のみを説明します。

あなたができることは次のようなものです:

  1. たとえば、5ミリ秒のブロックにわたる信号の平均(二乗平均)ラウドネスを計算します。 (これまでにこれを行ったことがないため、適切なブロックサイズがどのようになるかわかりません。)
  2. FFTアルゴリズムを使用して、「ブロックされた」信号のフーリエ変換を行います。
  3. 最大の大きさを持つ変換された信号のコンポーネントを見つけます。

フーリエ変換は基本的に、信号に存在するすべての周波数の強度を計算する方法です。 「ブロックされた」信号に対してこれを行うと、ビートの周波数が最も強くなると期待されます。

BPMに関するほとんどの情報を含む特定の周波数(低音など)に焦点を合わせるために、最初にフィルターを適用する必要があるかもしれません。

6
Thomas

Beats per Minuteを検出するためのかなり確かな実装があるように見えるこのライブラリを見つけました。 http://soundtouchdotnet.codeplex.com/

これは http://www.surina.net/soundtouch/index.html に基づいています。これはかなりの数のDJプロジェクトで使用されています http://www.surina.net/soundtouch/ applications.html

5
eandersson

まず、Hallgrimが生成しているのは、パワースペクトル密度関数ではありません。任意の信号の統計的周期性は、自己相関関数を介して引き出すことができます。自己相関信号のフーリエ変換は、パワースペクトル密度です。 0 Hz以外のPSDの支配的なピークは、信号の有効周期(Hz)に対応します...

1
pete

BASSオーディオライブラリとBASS.NETラッパーをチェックアウトすることをお勧めします。組み込みのBPMCounterクラスがあります。

この特定の関数の詳細は、 http://bass.radio42.com/help/html/0833aa5a-3be9-037c-66f2-9adfd42a8512.htm にあります。

0
Matt Williams

簡単な方法は、ビートに合わせてユーザーがボタンをリズムに合わせてタップし、タップ数を時間で割ることです。

0
Lucius Kwok