0

非常に簡単なサウンド スペクトラム アナライザーをランダムに作成します。

この python コードを考える:
http://rosettacode.org/wiki/Fast_Fourier_transform#Python
次のように実装:

import math
from cmath import exp, pi

def fft(x):
    N = len(x)
    if N <= 1: return x
    even = fft(x[0::2])
    odd =  fft(x[1::2])
    return ([even[k] + exp(-2j * pi * k / N) * odd[k] for k in xrange(N / 2)] + 
            [even[k] - exp(-2j * pi * k / N) * odd[k] for k in xrange(N / 2)])

#res = fft([1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0])
res = [math.sin(k) / 2.0 + 0.5 for k in xrange(64)]  # positive sine wave
res = fft(res)

for k in xrange(64/2):
    # get the amplitude...
    sqr = math.sqrt(res[k].real * res[k].real + res[k].imag * res[k].imag)
    if sqr > 0:
        print 20 * math.log10(sqr)  # ...in decibels
    else:
        print "-INF"

次の結果が得られます。

30.1160980385
-22.9398603241
-18.5295301528
-15.0005952198
-11.9809319241
-9.15035811436
-6.26269080991
-3.05038111824
0.930742121289
6.85461898041
23.4890109499 <-- PEAK
11.1462405429
4.62796511517
1.22261338459
-1.03611868864
-2.69639200998
-3.98905968693
-5.03263380282
-5.89570135908
-6.62130526828
-7.23808293566
-7.76594168565
-8.21919399668
-8.60840088318
-8.94151058446
-9.22459042752
-9.46231245749
-9.6582838436
-9.81527579404
-9.93538377539
-10.0201395611
-10.070588143

これはかなり問題ありません。入力正弦波の周波数でおそらく 23 dB のピークがあり、すべて問題ないようです。

唯一のことは、最初の値は何ですか: 30.1160980385? 非常に大きな低音が流れていますか?または、アルゴリズムの欠陥である可能性が高いです。この場合、どうすれば修正できますか。

最後の質問。fft に負の値を入力しても問題ありませんか? 上記の例では、[0,1] の範囲で常に正の正弦波を使用しました。[-1,1] の範囲の値を渡したい場合、すべてを台無しにしますか?

編集:

ネタバレでしたので編集を削除しました。ここでそれが何であるかを読むことができます:

ウィンドウ関数適用後の FFT 予期しない周波数シフト

4

1 に答える 1

2

正弦波のオフセットが +0.5 であるため、DC 成分が大きくなっているようです。正弦波の平均を 0 (たとえば +/- 0.5 または +/- 1.0 の範囲) にすると、スペクトルは DC (0 Hz) 端でより良く見えるはずです。

また、FFT の前にウィンドウ関数を使用していないため、スペクトルの漏れ(スペクトルの「不鮮明」) が発生し、これが DC 成分の影響を悪化させる可能性があることにも注意してください。

于 2013-10-04T10:25:18.750 に答える