2009-03-02 25 views
95

私はPythonでグラフィカルスペクトルアナライザを作成しようとしています。高速フーリエ変換を使用してオーディオを分析する

現在、1024バイトの16ビットデュアルチャネル44,100 Hzサンプルレートオーディオストリームを読み込み、2つのチャネルの振幅を平均化しています。だから私は256の署名されたショートの配列を持っています。私はnumpyのようなモジュールを使ってその配列上にfftをプリフォームし、結果を使ってグラフィカルスペクトルアナライザを作成したいと思います。

私は高速フーリエ変換と離散フーリエ変換に関するウィキペディアの記事を読んだことがありますが、結果として得られる配列が何を表しているかはまだ不明です。

[ -3.37260500e+05 +0.00000000e+00j 7.11787022e+05 +1.70667403e+04j 
    4.10040193e+05 +3.28653370e+05j 9.90933073e+04 +1.60555003e+05j 
    2.28787050e+05 +3.24141951e+05j 2.09781047e+04 +2.31063376e+05j 
    -2.15941453e+05 +1.63773851e+05j -7.07833051e+04 +1.52467334e+05j 
    -1.37440802e+05 +6.28107674e+04j -7.07536614e+03 +5.55634993e+03j 
    -4.31009964e+04 -1.74891657e+05j 1.39384348e+05 +1.95956947e+04j 
    1.73613033e+05 +1.16883207e+05j 1.15610357e+05 -2.62619884e+04j 
    -2.05469722e+05 +1.71343186e+05j -1.56779748e+04 +1.51258101e+05j 
    -2.08639913e+05 +6.07372799e+04j -2.90623668e+05 -2.79550838e+05j 
    -1.68112214e+05 +4.47877871e+04j -1.21289916e+03 +1.18397979e+05j 
    -1.55779104e+05 +5.06852464e+04j 1.95309737e+05 +1.93876325e+04j 
    -2.80400414e+05 +6.90079265e+04j 1.25892113e+04 -1.39293422e+05j 
    3.10709174e+04 -1.35248953e+05j 1.31003438e+05 +1.90799303e+05j... 

私はまさにこれらの数字は何を表しているか疑問に思って、私はそれぞれのために高さの割合にこれらの数字を変換する方法を:これは、アレイが、私はnumpyの使用して私のアレイ上のFFTをプリフォームした後、次のようになります32バー。また、私は一緒に2つのチャンネルを平均する必要がありますか?

答えて

187

表示している配列は、オーディオ信号のフーリエ変換係数です。これらの係数を使用して、オーディオの周波数成分を得ることができます。 FFTは複素数値の入力関数に対して定義されているので、入力がすべて実際の値であっても、出力する係数は虚数になります。各周波数の電力量を取得するには、各周波数のFFT係数の大きさを計算する必要があります。これはではなく、係数の実際の成分であるであり、その実数成分と虚数成分の二乗和の平方根を計算する必要があります。つまり、係数がa + b * jの場合、その大きさはsqrt(a^2 + b^2)です。

各FFT係数の大きさを計算したら、各FFT係数がどのオーディオ周波数に属しているか把握する必要があります。 NポイントのFFTは、0から始まるN個の等間隔の周波数で信号の周波数成分を与えます。サンプリング周波数は44100サンプル/秒です。 FFTのポイント数は256、周波数間隔は44100/256 = 172 Hz(約)

あなたの配列の最初の係数は0の周波数係数になります。これは基本的にすべての周波数の平均電力レベルです。残りの係数は172Hzの倍数で0からカウントダウンされ、128になります.FFTでは、サンプルポイントの半分までの周波数しか測定できません。あなたが刑罰のための熱狂者である理由を知る必要があるが、基本的な結果は、より低い周波数が複製されるか、またはより高い周波数のバケットにaliasedが複製されることである場合、Nyquist Frequencyおよびのこれらのリンクを読んでください。したがって、周波数は0から始まり、N/2係数まで各係数に対して172 Hz増加し、N-1係数まで172 Hz減少します。

これは、開始するのに十分な情報である必要があります。ウィキペディアよりもはるかに親しみやすいFFTの導入をご希望の場合は、Understanding Digital Signal Processing: 2nd Ed.をお試しください。それは私のために非常に役立った。

これは、これらの数字が表すものです。各周波数成分の大きさをすべての成分の大きさの合計でスケーリングすることによって、高さのパーセンテージに変換することができます。ただし、それは相対周波数分布の表示に過ぎず、各周波数の実際の電力ではありません。周波数成分に対して可能な最大の大きさでスケーリングを試みることができますが、それがうまく表示されるかどうかはわかりません。実行可能なスケーリングファクタを見つける最も速い方法は、適切な設定を見つけるために大音量および柔らかいオーディオ信号を試すことです。

最後に、オーディオ信号全体の周波数成分を全体的に表示したい場合は、2つのチャンネルを平均化する必要があります。ステレオオーディオをモノラルオーディオにミキシングし、組み合わせた周波数を表示します。右と左の周波数の2つの別々のディスプレイが必要な場合は、各チャンネルでフーリエ変換を個別に実行する必要があります。

+3

+1と私に新しいイディオムを覚えさせることに注意してください。私は英語のネイティブスピーカーではありません。;) – macbirdie

+1

+1素晴らしい、これは私が間違っていたことを理解するのに役立ちました。 – Davido

+4

+1 - 私はFFTについて既に知っていますが、ウェブ上での英語の簡単な説明の1つです。 – OldTinfoil

10

長さが256/44100 = 0.00580499秒のサンプルがあります。つまり、周波数分解能は1/0.00580499 = 172 Hzです。 Pythonから出てくる256の値は、基本的に86 Hzから255 * 172 + 86 Hz = 43946 Hzまでの周波数に対応しています。出てくる数字は複素数です(したがって、2番目の数字の最後にある "j"です)。

編集:FIXED誤った情報

あなたはSQRT(私は + J )i、jは実部と虚部が、RESPを計算することにより、振幅に複素数を変換する必要があります。

32のバーが必要な場合は、4つの連続する振幅の平均を取って、256/4 = 32バーを必要に応じて取得する必要があります。

+0

こんにちは、最初の(間違った)回答を申し訳ありません...数学の権利を取得していません。これは正しいはずです。 –

+4

cが複素数である場合、偉大な解答のためにsqrt(c.real ** 2 + c.imag ** 2)== abs(c) – tzot

25

このスレッドは歳ですが、非常に役に立ちました。私はちょうどこれを見つけ、同様のものを作成しようとしている人に自分の意見を伝えたいと思っていました。アンティが示唆するように、バーへの分割として

この均等バーの数に基づいてデータを分割することによって、行われるべきではありません。最も有用なのは、データをオクターブ部分に分割することです。各オクターブは前の周波数の2倍です。 (すなわち、100hzは50hzより1オクターブ上で、25hzより1オクターブ上回る)。

必要なバーの数に応じて、範囲全体を1/Xオクターブの範囲に分割します。 バー上の与えられた中心周波数に基づいて、あなたはからバーの上限と下限を取得:

upper limit = A * 2^(1/2X) 
lower limit = A/2^(1/2X) 

次の隣接する中心周波数を計算するために、あなたは、同様の計算を使用します。

next lower = A/2^(1/X) 
next higher = A * 2^(1/X) 

これらの範囲に収まるデータを平均して、各バーの振幅を取得します。

例: 1/3オクターブの範囲に分割し、1kHzの中心周波数から開始します。

Upper limit = 1000 * 2^(1/(2 * 3)) = 1122.5 
Lower limit = 1000/2^(1/(2 * 3)) = 890.9 

考える44100hz及び1024個のサンプル(各データポイント間43hz)我々は、値平均化すべきである21 26を介して(890.9/43 = 20.72〜21及び1122.5/43 = 26.10〜26)

( 1/3オクターブのバーは〜40hzと〜20khzの間の30のバーの周りにあなたを得るでしょう)。 今のところわかるように、上がるにつれて、より大きな範囲の数値が平均化されます。低いバーは、通常、1または少数のデータポイントしか含まない。高いバーは数百ポイントの平均値になります。その理由は、86hzは43hzよりも上のオクターブです... 10086hzは10043hzとほとんど同じですが。

関連する問題