1

このコードを取得しましたが、0 から約 1050 までのランダムな頻度を返し続けています。

私のデータ長は 1024、サンプル レートは 8192、データはマイクからの入力データで満たされた短い配列です。


float *iSignal = new float[2048];
float *oSignal = new float[2048];
int pitch = 0;

for(x=0;x<=1024;x++) {
    iSignal[x] = data[x];
}

fft(iSignal,oSignal,1024); //Input data, output data, length of input and output data

for(int y=0;y< 2048;y+=2) {
if((pow(oSignal[y],2)+pow(oSignal[y+1],2))>(pow(oSignal[pitch],2)+pow(oSignal[(pitch)+1],2))) {
        pitch = y;
    }
}

double pitchF = pitch / (8192.0/1024);
printf("Pitch: %f\n",pitchF);

ありがとう、

ニール。

編集:コードを変更しましたが、まだランダムな周波数を返しています。

4

4 に答える 4

7

oSignalが実数部と虚数部が交互になるような方法で複素数で満たされていると仮定すると、変更するのに役立つ場合があります

for(int y=0;y< 8191;y++)

for(int y=0;y< 8191;y+=2)

編集: 1024 個のサンプルしか渡していないことにさえ気づきませんでした。周波数領域のサンプルと同じ数の時間領域のサンプルを渡す必要があります。この場合は 4096 です。

編集:もう1つ:明らかに、何かの基本周波数を見つけようとしています。その何かがコンピューターで生成された音または人間の口笛 (どちらも非常に純粋な音) でない限り、結果にがっかりするかもしれません。あなたが投稿した簡単な方法は、フルートではほとんど機能しません。

編集:声とギターの場合、あなたは運が悪い. しばらく前に、周波数領域を表示するプログラムを書きました。試してみてください。問題が表示されます。興味があれば、利用可能なソースもあります。

最終編集:ピッチ検出に関するウィキペディアの記事を読みたいと思うかもしれません。時間領域のアプローチに集中します。

于 2009-08-29T13:06:51.760 に答える
1

iSignal[1025]..iSignal[8191] にはランダムなデータが含まれているようです。0 に設定することもできます。しかし、データ長が 1024 (または 1025) の場合、なぜ 8192 を fft() に渡すのでしょうか?

また、整数除算の精度がいくらか失われます。ダブルピッチに変更 F = ピッチ / (8192.0/1024);

fft 関数は、実数または複素数の入力データを想定していますか? 複雑なデータが予想される場合は、iSignal のエントリを 1 つおきに 0 に設定する必要があります。

于 2009-08-29T13:07:32.790 に答える
0

2つのこと:

  • fft関数を正しく使用していますか?出力は組織化された複雑な配列であるかのように[R_1 I_1 R_2 I_2 ...]扱いますが、入力配列は組織[R_1 R_2 R_3 ... R_1024 I_1 I_2 ...]されたものとして扱い、Henrikが言うように、複雑な部分は初期化されないままにします。
  • ピーク検出は非常に原始的ですが、単純な入力(単一のギターの刺し傷など)に対しては実行する必要があります。人間の声で使用するには、ほぼ確実に、より洗練されたアプローチが必要です。

既知の単純な(つまり純粋な正弦)信号を入力として入力してみましたか?

于 2009-08-30T15:35:30.023 に答える
0

「0から約1050までのランダムな周波数」 - 典型的なオーディオ信号は周波数の組み合わせで構成されていませんか? サンプル レートは 8192 Hz であるため、FFT は最大 8192/2 = 4096 Hz を検出できます。多くの周波数の組み合わせが見られると思いますが、それらを「ランダム」とは呼びません。

なぜあなたは驚いたのですか?私は何を取りこぼしたか?

于 2009-08-29T13:07:06.643 に答える