0

私は今、オーディオ信号処理の初心者です。ピッチ検出アルゴリズムを実装しようとしています。ケプストラムのいくつかのステップを見つけました。

result1 = IFFT(log(abs(FFT(Audio Input))))
peak = max(result);
out_frequency = 1/peak; // last step

したがって、FFTとIFFTのライブラリとしてkissfftとportaudioを使用して、これらのアルゴリズムをCで実装します。問題は、IFFTの結果を取得し、周波数を抽出する最後の手順を実行した後、期待した結果ではありません。(注。私は音符A(440Hz)で歌ってテストします)

Cepstrumの最後のステップを見逃しているのか、それとも間違っているのかわかりません。

テストするマイクは私のラップトップマイクです。これはコンデンサーマイクであることがわかっています。MICをDynamicMicに変更する必要がありますか、それとも通常のLabtopマイクを使用しても問題ありません。

聞いて私が実装したコードです

kiss_fft_cpx cin[FFT_SIZE];
kiss_fft_cpx cout[FFT_SIZE];
kiss_fft_cpx fftBins[FFT_SIZE];
for ( i = 0; i <FFT_SIZE; i++){
    cin[i].r = zero;
    cin[i].i = zero;
    cout[i].r = zero;
    cout[i].i = zero;
    fftBins[i].r = zero;
    fftBins[i].i = zero;
}
for(j=0;j < FFT_SIZE;j++){
    cin[j].r = *in++ ;
}
kiss_fftr_cfg fftConfiguration = kiss_fftr_alloc( FFT_SIZE, 0, NULL, NULL );
kiss_fftr_cfg ifftConfiguration = kiss_fftr_alloc( FFT_SIZE, 1, NULL, NULL );

// FFT...
kiss_fftr( fftConfiguration, (kiss_fft_scalar*)cin, fftBins );
for(i = 0; i<FFT_SIZE;i++){
    fftBins[i].i = log(fabs(fftBins[i].r));
    fftBins[i].r = zero;
}
// iFFT...
kiss_fftri( ifftConfiguration, fftBins, (kiss_fft_scalar*)cout );
double maxi = 0;
double maxr = 0;
for(i = 0; i<FFT_SIZE;i++){
    if(maxi<cout[j].i){
        maxi = cout[j].i;
    }
    if(maxr<cout[j].r){
        maxr = cout[j].r;
    }
}
printf("%f\t%f\n",maxi,maxr);
double result;
result = 1./maxr;
printf("result = %f\n",result);
free(fftConfiguration);
free(ifftConfiguration);

由来

4

1 に答える 1

1

複雑な配列(kiss_fft_cpx)を作成し、それを実際の配列(kiss_fft_scalar)として使用しています。kiss_fft_scalarを使用して、マイクサンプルをkiss_fftrに送信することをお勧めします。

実際のfftは、N / 2+1の複素数ポイントを返します。

大きさを計算するときは、虚数部を無視しないでください。sqrt(re ^ 2 + im ^ 2)を使用するか、ケプストラムのピークに影響を与えずにsqrtをスキップできます。

対象の周波数は、fftサイズとサンプリング周波数に合わせて調整する必要があります。

于 2012-08-31T19:42:33.700 に答える