2011-07-03 10 views
5

私は最近、イムは、私は良い結果を得ていない午前として、私は正常に実装されている場合、あまりにもわからない、すなわち導出とコムフィルタアルゴリズム#1 :: http://archive.gamedev.net/reference/programming/features/beatdetection/page2.aspこのビート検出アルゴリズムの実装に関するヘルプ?

、ここで見つけるビート検出コードを実装しようとしました。誰かがこれをうまく実装したのか、一般的に手助けしたいと思っている良い人に向かっているのだろうかと疑問に思っていました。ここに私の実装です:私は取得しています

//Cycle through Tempo's (60 to 200) incrementing each time by 10 
for (int i = (int)mintempo; i <= maxtempo; i += 10) 
{ 
    //Clear variables to be used 
    curtempo = i; 
    fftPulse.Clear(); 
    offset = 0; 
    energy = 0; 
    short[] prevBuffer = null; 

    //Calculate ti 
    ti = (60/curtempo) * 44100; 
    ti = Math.Round(ti, 0); 

    //Generate pulse train 
    for (int j = 0; j < pulseTrain.Length; j++) 
    { 
     if ((j % ti) == 0) 
      pulseTrain[j] = short.MaxValue; 
     else 
      pulseTrain[j] = 0; 
    } 

    //Compute FFT of the pulseTrain array 
    while (offset < pulseTrain.Length) 
    { 
     //Generate block samples (1024 is my blocksize) 
     short[] fftPulseBuffer = new short[po.blocksize/2]; 

     //Store samples from pulseTrain in a 1024 block buffer for passing to the FFT algorithm 
     index = 0; 
     for (int j = offset; j < (offset + (po.blocksize/2)) && j < pulseTrain.Length; j++) 
     { 
      fftPulseBuffer[index] = pulseTrain[j]; 
      index++; 
     } 

     //Initialize prevBuffer, which contains samples from the previous block, used in conjunction with the current block for the FFT 
     if (prevBuffer == null) 
      prevBuffer = new short[po.blocksize/2]; 

     //Calculate the FFT using the current and previous blocks 
     fftPulse.Add(CalculateFFT(fftPulseBuffer,prevBuffer)); 

     //Set prevBuffer and increment to next block start position 
     prevBuffer = fftPulseBuffer; 
     offset += (po.blocksize/2); 
    } 

//Calculate energy 
    for (int j = 0; j < intendomainarr.Count; j++) 
    { 
     double[] signalarr = intendomainarr[j]; 
     double[] pulsearr = fftPulse[j]; 
     for (int x = 0; x < signalarr.Length; x++) 
     { 
      energy += Math.Abs(signalarr[x] * pulsearr[x]); 
     } 
    } 

    //Get current best tempo match 
    if (energy > maxenergy) 
    { 
     chosentempo = curtempo; 
     maxenergy = energy; 
    } 
} 

結果は私の.wavファイルのみ60-120BPM間のテンポを持っているように、ケースすべきではない、通常は190と200BPMの周りに、常に非常に高いです。

WAVファイル(44.1Khz、16ビット、モノ)を使用しているため、一部の数式が1つのチャンネルでしか動作しないように少し修正(つまりエネルギーを計算)していることに注意してください。私の実装に矛盾があるかどうか確認したいのですが?私はライブラリを使用しているので、FFTの部分については心配していません。

ありがとうございました!

答えて

3

エネルギー対周波数のプロットを作成します。

高調波はベース信号とほぼ同じエネルギーを持ち、実際の周波数が周波数ビンの半分になると、2次高調波のピークがサンプリングされ、2つのサンプルを真の周波数

この効果を克服するには、より高い周波数を少しペナルティする必要があります。


C#は、リアルタイムでこのようなアルゴリズムの実装のための不合理な選択ではないか、一括バッチ処理のために、それはアルゴリズム開発と微調整のために恐ろしいですが、注意してください。私はMatLab(または無料のクローン、Octave)を使用してアルゴリズムを正しく取得することをお勧めします。コードをC#(またはC++)に変換するだけで、いくつかのテストケースで作業します。

0

私はこれが欲しかっされている場合はかなりよく分からないが、このブロック内のコメントは、コードに合わない:

//Generate block samples (1024 is my blocksize) 
    short[] fftPulseBuffer = new short[po.blocksize/2]; 

    //Store samples from pulseTrain in a 1024 block buffer for passing to the FFT algorithm 
    index = 0; 
    for (int j = offset; j < (offset + (po.blocksize/2)) && j < pulseTrain.Length; j++) 
    { 
     fftPulseBuffer[index] = pulseTrain[j]; 
     index++; 
    } 

コードfftPulseBufferによるので、最初のコメントでは、サイズ512を持っており、それは1024年と言います

+0

おっと、申し訳ありませんが、コメントに誤りがありました。サイズは実際には512ですが、私はその部分を試してみます。 – dspboy

関連する問題