2013-10-04 2 views
0

매우 쉬운 사운드 스펙트럼 분석기를 무작위로 구축하십시오. FFT 값이 잘못 되었습니까?

이 파이썬 코드를 감안할 때 : http://rosettacode.org/wiki/Fast_Fourier_transform#Python

는 다음과 같이 구현 :

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 

꽤 OK입니다

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" 

나는 이러한 결과를 얻을 수 있습니다. 나는 23dB 피크를 입력 사인파의 주파수에서 가정하고 모든 것이 잘 보입니다.

유일한 것, 첫 번째 값은 무엇입니까? 30.1160980385? 그 중 일부는 매우 큰 저음인가요? 또는 알고리즘의 결함 일 가능성이 높습니다. 이 경우 어떻게 수정해야합니까?

마지막 질문. fft가 음수 값을 입력해도 괜찮습니까? 위의 예에서 나는 항상 양의 값인 [0,1] 인 정현파를 사용했습니다. [-1,1] 범위의 값을 전달하려면 모든 것을 망쳐야합니까?

편집 : 그것은 오프 주제이기 때문에

내가 편집을 제거했습니다. 당신은 여기에 대해 무엇 읽을 수 있습니다

FFT unexpected frequency shift after window function application

+0

마치 이것이 사실이라면 반드시 FFT를 직접 구현하는 방법을 배우는 학습 프로젝트입니다. 'scipy.fftpack'에서 견고한 라이브러리를보고 싶다면 순수 파이썬 솔루션보다 빠를 것이다. 예를 들어 http://stackoverflow.com/questions/19122157/fft-bandpass-filter-in-python/19124329#19124329를 살펴보고 SO의 라이브러리를 다른 용도로 사용하십시오. – Hooked

답변

2

당신은 분명히 큰 DC component을 인해 사인파가 0.5의 오프셋 (offset)는 사실에. 사인파가 제로 평균 (즉, +/- 0.5 또는 +/- 1.0의 범위)으로 설정하면 스펙트럼이 DC (0 Hz) 끝에서 더 잘 보입니다.

FFT 이전에 window function을 사용하지 않았으므로 spectral leakage (스펙트럼의 "번짐")이 발생하고 모든 DC 구성 요소의 영향을 악화시킬 수 있습니다.

+0

감사합니다. 이제 창 함수를 구현하고 OP 게시글을 편집했습니다. 웬일인지 지금 최고점은 바뀌었다. 나는 코드를 아마도 엉망으로 만들었 을까? – user2464424

+0

미안 해요, 저는 파이썬 프로그래머가 아니므로, DSP 이론에 대한 일반적인 조언 만 할 수 있습니다. 코드는 제 훈련받지 않은 눈에게는 괜찮아 보이지만, 아직 디버깅을 할 수있는 것처럼 들립니다. –

+0

OK thanks 아마도 나는 새로운 질문을 시작할 것입니다. – user2464424

관련 문제