2009-08-30 7 views
1

私は前に尋ねたものと同様の質問をして申し訳ありませんが(FFT Problem (Returns random results))、ピッチ検出と自己相関を調べてピッチ自己相関を用いた検出。自己相関は、マイク入力(ハイパスフィルタを使用)でランダムな結果を返します。

私は歌うユーザーのピッチ検出をしようとしています。問題は、ランダムな結果を返すことです。私はhttp://code.google.com/p/yaalp/からいくつかのコードを取得しましたが、これはC++に変換して変更しました(下記参照)。私のサンプルレートは2048、データサイズは1024です。私は正弦波とマイク入力の両方のピッチを検出しています。正弦波の周波数は726.0であり、それは722.950820であることがわかりましたが(これは問題ありません)、マイクのピッチを約100から約1050までの乱数として検出します。

私は今ありますハイパスフィルタを使用してDCオフセットを除去しても動作しません。私はそれを正しくやっていますか?もしそうなら、それを解決するために他に何ができますか?どんな助けでも大歓迎です! (固定)

おかげで、

ニール。

編集:カットオフ30hzのハイパスフィルタを実装するようにコードを変更しました(What Are High-Pass and Low-Pass Filters?から、コンバージョンを使用してローパスフィルタをハイパスに変換する方法を教えてください)。ランダムな結果。それをVSTホストに接続し、VSTプラグインを使用してスペクトルを比較することは、残念なことに私にとっては選択肢ではありません。

編集:すべての人の助けを借りてくれてありがとうございましたが、今は新しいコードを使用しても問題はありません。

+1

BTW:割り当てたメモリの割り当てを解除することはないので、メモリ管理が改善されるはずですが、アルゴリズムを実行しておきたいと思います。しかし、あなたはそれを忘れるべきではありません! – mmmmmmmm

+3

なぜこのタグはC++ですか?そのコードはC++ではありません。 – GManNickG

+0

そこには1つのC++ラインはありませんが、Niallはこれを好きです。 – gimpf

答えて

0

私はあなたのコードに問題が表示されていないが、私はCでダメよんしかし、私は、問題を見つけるために、次の試してみます。ここで、既知で結果のデータと

  • 実行を、例えば入力としてSIN(x)が小さいデータサイズを有する
  • ランを用いて(例えば2)

は既知正しいものと結果を比較します。あなたはインターネット上のそれらを見つけることができるはずです、または手でそれらを行う。

ランダムの場合:同じ入力、異なる出力、おそらく変数の初期化にいくつかのバグがあります。デバッガと既知の入力を使用して、すべての変数、特に配列のすべての要素が適切に初期化されていることを確認します。

+0

正弦波からの入力は多かれ少なかれ正確な結果をもたらしますが、マイクからの入力は約100から約1050のランダムな結果になります。しかし、マイクのデータが正しいことを確認しました。 – Niall

1

問題は、あなたのfindBestCandidates()関数である:

この関数内あなたは「長さ - 1」まで0からの「入力」のアレイにアクセスします。 detectPitchCalculation()関数内でこの関数を呼び出すと、 'inputs'は 'results'、 'length'は 'nHiPeriodInSamples'です。 しかし、 'results'は 'nHiPeriodInSamples - nLowPeriodInSamples - 1'にのみ割り当てられます。 したがって、 'nLowPeriodInSamples'が大きい場合は、findBestCandidates()関数内の未割り当てのランダムなメモリにアクセスします。

EDIT:

別のバグはあなたが「結果」配列detectPitchCalculation()関数の各「nResolution」エントリを埋めるが、findBestCandidates()関数内の各エントリにアクセスすることです(「入力」を介して引数)。しかし、あなたは 'nResolution = 1'でdetectPitchCalculation()を呼び出しているので、これはあなたの特定の問題を説明していないので、もう少し見ていきます。しかし、あなたがより高い解像度でそれを呼び出すならば、間違いなく問題になります。

+0

nHiPeriodInSamplesをnHiPeriodInSamples - nLowPeriodInSamples - 1に変更しましたが、まだマイク入力のランダムな値が返されています。 – Niall

+0

長さが 'nHiPeriodInSamples - nLowPeriodInSamples'なので ' - 1'のままにしておきます。つまり、0から 'nHiPeriodInSamples - nLowPeriodInSamples - 1'までのインデックスにアクセスできます。しかし、これはあなたのランダムな問題を解決しないでください私はあなたのプログラムをもう一度見てみましょう。 – mmmmmmmm

2

私は健全なエキスパートではありませんが、44100(1秒あたりのサンプル数)とサンプリングして1024のデータポイントを使用している場合は、約40分の1秒のデータで作業しています。私はあなたが選んだピースに応じて現在のピッチが大きく変わっていることを私に驚かせません。音声の平均ピッチやメインピッチを探したい場合は、約1秒分のデータが必要になると思います。

+0

したがって、1秒あたりのサンプル数が多かれ少なかれ正確な結果が得られますか? – Niall

+2

@Nail:@Jensは1024よりも多くのサンプルが必要であることを示唆していると思われます。私が間違っていないと、以前の質問で@avakarと同様の表示があります。http:// stackoverflow .com/questions/1351381/fft-problem-returns-random-results/1351398#1351398 –

1

44.1 kHzのサンプリング周波数では、1024サンプルはわずか23 ms相当のデータにすぎません。人間の歌手のピッチを計算するためにこれが単に不十分なデータである可能性はありませんか?

つまり、私が23ms持続させることができる音は、おそらく私が多くのピッチコントロールを持っているとは限りません。私は、この種の測定が、より長い時間にわたって非常に長く行われることを期待しています。

+0

したがって、1秒あたりのサンプル数が多かれ少なかれ正確な結果が得られますか? – Niall

+1

私の親愛なる、あなたは何かを体系化しようとする前に、少なくとも理解の大雑把な一見を持っている必要があります!より多くのサンプル - >長い時間;毎秒多くのサンプル:同じ量のサンプルでは時間がかかりません。一定量のサンプルでは、​​1秒あたりのサンプル数が減ります。 – gimpf

関連する問題