3

C# でリアルタイム オーディオから「1 分あたりのビート数」を決定しようとしています。私が検出しているのは音楽ではありませんが、一定のタッピング音です。私の問題は、これらのタップ間の時間を決定することです。これにより、WaveIn.cs クラスを使用して試した「1 分あたりのタップ数」を決定できますが、そのサンプリング方法がよくわかりません。1 秒間に設定された数のサンプルを分析できません。サンプル間の時間を知るために、1秒間に正確なサンプル数を読み取る方法が本当にわからないだけだと思います。

私を正しい方向に導くための助けをいただければ幸いです。

4

3 に答える 3

3

どの WaveIn.cs クラスを使用しているかはわかりませんが、通常、オーディオを録音するコードでは、A) コードに録音を開始するように指示し、その後、コードに停止を指示すると、次のいずれかになります。この期間中に記録されたデータを含む配列 (通常は short[] 型) を返します。または B) 指定されたバッファー サイズで記録を開始するようにコードに指示し、各バッファーがいっぱいになると、コードは、いっぱいになったバッファーへの参照を使用して定義したメソッドへのコールバックを作成します。このプロセスは、指定するまで続行されます。録音を停止します。

録音フォーマットがサンプルあたり 16 ビット (別名 2 バイト)、1 秒あたり 44100 サンプル、およびモノ (1 チャネル) であると仮定しましょう。(A) の場合、録音を開始してちょうど 10 秒後に録音を停止するとします。長さが 441,000 (44,100 x 10) 要素の short[] 配列になります。「タップ」を検出するためにどのアルゴリズムを使用しているかはわかりませんが、この配列の要素 0、要素 22,050、要素 44,100、要素 66,150 などでタップを検出するとします。これは、すべてのタップを検出していることを意味します。 5 秒 (22,050 は 1 秒あたり 44,100 サンプルの半分であるため)、つまり、1 秒あたり 2 回のタップがあるため、120 BPM になります。

(B) の場合、44,100 サンプル (別名 1 秒) の固定バッファ サイズで記録を開始するとします。各バッファーが入ってくると、要素 0 と要素 22,050 にタップが見つかります。上記と同じロジックで、120 BPM を計算します。

お役に立てれば。一般的にビート検出では、比較的長い時間記録し、大量のデータ配列からビートをカウントするのが最善です。「瞬間的な」テンポを推定しようとするのは難しく、エラーが発生しやすいのと同じように、録音のピッチをリアルタイムで推定することは、完全な音符を録音する場合よりも困難です。

于 2009-08-11T21:55:24.567 に答える
2

サンプルを「タップ」と混同しているのではないかと思います。

サンプルは、特定の時点での音波の高さを表す数値です。一般的なWaveファイルは1秒間に44,100回サンプリングされる可能性があるため、ステレオ用に2つのチャネルがある場合、1秒間に88,200の16ビット数(サンプル)があります。

これらの数値をすべて取得してグラフ化すると、次のようになります。

代替テキスト
(出典:vbaccelerator.com

What you are looking for is this peak ------------^

それがタップです。

于 2009-08-11T21:04:54.530 に答える
1

同じ WaveIn.cs について話していると仮定すると、WaveLib.WaveInRecorder のコンストラクターは WaveLib.WaveFormat オブジェクトをパラメーターとして受け取ります。これにより、オーディオ形式を設定できます。サンプルレート、ビット深度など。オーディオサンプルをスキャンしてピークを探すか、「タップ」を検出し、ピーク間のサンプルの平均距離を記録します。

オーディオ ストリームのサンプル レート (例: 44100 サンプル/秒) がわかっているので、平均ピーク距離 (サンプル単位) を取得し、1/(サンプル レート) を掛けてタップ間の時間 (秒単位) を取得し、タップ間の時間 (分単位) を取得するには 60、タップ/分を取得するには反転します。

それが役立つことを願っています

于 2009-08-11T21:11:11.367 に答える