6

MATLAB でフーリエ変換を正しい方法で使用しているかどうか疑問に思っています。曲の周波数の平均振幅をすべて取得したいと考えています。テスト目的で、 Audacityを使用して 8 kHz のモノラル ウェーブ ファイルに変換したベートーベンの「エリーゼのために」の無料の mp3 ダウンロードを使用しています。

私のMATLABコードは次のとおりです。

clear all % be careful

% load file
% Für Elise Recording by Valentina Lisitsa 
% from http://www.forelise.com/recordings/valentina_lisitsa
% Converted to 8 kHz mono using Audacity
allSamples = wavread('fur_elise_valentina_lisitsa_8khz_mono.wav');


% apply windowing function
w = hanning(length(allSamples));
allSamples = allSamples.*w;


% FFT needs input of length 2^x
NFFT = 2^nextpow2(length(allSamples))


% Apply FFT
fftBuckets=fft(allSamples, NFFT); 
fftBuckets=fftBuckets(1:(NFFT/2+1)); % because of symetric/mirrored values


% calculate single side amplitude spectrum, 
% normalize by dividing by NFFT to get the 
% popular way of displaying amplitudes
% in a range of 0 to 1
fftBuckets = (2*abs(fftBuckets))/NFFT; 

% plot it: max possible frequency is 4000, because sampling rate of input
% is 8000 Hz
x = linspace(1,4000,length(fftBuckets));
bar(x,fftBuckets);

出力は次のようになります。 ここに画像の説明を入力

  1. 私のコードが正しいかどうか誰か教えてもらえますか? 特に0付近のピークが気になります。
  2. NFFT正規化するには、またはで割る必要がありlength(allSamples)ますか?
  3. 私にとって、これは棒グラフのようには見えませんが、プロットしている値が多いためでしょうか?

ヒントをありがとう!

4

2 に答える 2

6
  1. 「正しい」の定義に依存します。これはあなたが意図したことをやっていると思いますが、おそらくあまり役​​に立ちません。代わりに2Dスペクトログラムを使用することをお勧めします。これは、周波数コンテンツに関する時間局所化された情報が得られるためです。

  2. FFT 出力を正規化する唯一の正しい方法はありません。さまざまな慣習があります (たとえば、ここでの議論を参照してください)。コード内のコメントは、0 から 1 の範囲が必要であることを示しています。入力値が-1から1の範囲にある場合、ビンの数で割るとそれが達成されます。

  3. まあ、まさに!

また、y 軸を対数目盛 (デシベル) でプロットすることをお勧めします。これは、人間の耳がラウドネスを大まかに解釈する方法です。

于 2012-07-03T11:22:58.400 に答える
2

私に飛び出す2つのこと:

  1. プロットに DC (index = 1) コンポーネントを含めている理由がわかりません。大したことではありませんが、もちろん、そのビンには頻度データが含まれていません
  2. length(allSamples)で割るよりも で割ったほうが正しい可能性が高いと思いますNFFT。その理由は、DC 成分を入力データの平均と等しくしたい場合は、で割ることlength(allSamples)が正しいことです。

ただし、オリが言ったように、何を計算しようとしているのかを正確に理解するまで、「正しい」正規化が何であるかを実際に言うことはできません。私は FFT を使用してパワー スペクトルを推定する傾向があるため、「DAC / rt-Hz」のような単位が必要です。これは、「DAC / Hz」のようなものが必要な場合とは異なる正規化につながります。

最終的には、FFT から得たいもの (単位を含む) を正確に考え、正しい正規化がどうあるべきか (必要に応じて FFT の定義から始めて) を自分で考え出すことに代わるものはありません。

また、MATLAB には 2 の累乗である配列の長さを使用する必要がないことにも注意してくださいfft(ただし、そうすることで FFT の実行が速くなる可能性があります)。ゼロ パディングを行うとリンギングが発生するため、それがアプリケーションにとって適切かどうかを検討する必要があります。

最後に、ピリオドグラム/パワー スペクトルが本当に必要な場合、MATLAB はなどperiodogramの関数を提供しpwelchます。

于 2012-07-03T16:03:53.690 に答える