2010-04-15 5 views
29

좋아요. 무슨 일을하려고하면 자주 발생하는 주파수를 감지 할 수있는 일종의 오디오 처리 소프트웨어입니다. 주파수를 충분히 오래 재생하면 (몇 밀리 초) 나는 긍정적 인 결과를 얻었습니다. 나는 FFT 또는 뭔가 similar 사용할 필요가 있지만 수학 분야에서 나는 빨아, 나는 인터넷 검색했지만 didn이 할 수있는 코드를 찾지 못했습니다.파이썬 주파수 감지

내가 목표로 삼고 자하는 목표는 자신에게 데이터 트로프 사운드를 보내고 초당 매우 낮은 비트 전송률 (5-10bps)을 요구하는 맞춤 프로토콜을 만드는 것입니다.하지만 수신 측 소프트웨어가 전송 측에서 매우 제한적이기 때문에 수신 소프트웨어가 (하드웨어/소프트웨어 모뎀을 사용할 수없는) 사용자 지정도 가능합니다.이 소프트웨어 (사운드 카드를 제외한 추가 하드웨어 없음)를 원합니다.

감사합니다.

+1

이것은 도움이 될 수 있습니다 (답글을 꼭 읽어보십시오) : http://www.keyongtech.com/5003865-frequency-analysis-without-numpy – ChristopheD

답변

37

aubio 라이브러리는 SWIG로 싸여 있으므로 Python에서 사용할 수 있습니다. 많은 기능 중에는 YIN 알고리즘과 일부 하모닉 콤 알고리즘을 포함하여 피치 검출/추정을위한 여러 가지 방법이 있습니다.

그러나 좀 더 간단한 것을 원한다면 얼마 전에 피치 추정을위한 몇 가지 코드를 작성 했으므로 가져 가거나 그대로 둘 수 있습니다. aubio 알고리즘을 사용하는 것만 큼 정확하지는 않지만 필요에 따라 충분할 수 있습니다. 기본적으로 데이터의 FFT에 창 (이 경우 블랙맨 창)을 곱하고 FFT 값을 제곱하며 가장 높은 값을 갖는 빈을 찾은 후 최대 값의 로그를 사용하여 피크 주위에서 2 차 보간을 사용했습니다. 기본 주파수를 찾기 위해 이웃하는 두 값을 비교합니다. 나가 찾아낸 몇몇 종이에서 가지고 간 2 차 보간법.

테스트 톤에서 상당히 잘 작동하지만 위에 언급 된 다른 방법보다 강력하거나 정확하지는 않습니다. 청크 크기를 늘리거나 정확도를 높이면 정확도를 높일 수 있습니다. 청크 크기는 FFT를 최대한 활용하기 위해 2의 배수 여야합니다. 또한, 나는 겹치지 않는 각 덩어리의 기본 피치만을 결정하고있다. 예상 된 피치를 쓰는 동안 PyAudio를 사용하여 사운드를 재생했습니다.

소스 코드 :

# Read in a WAV and find the freq's 
import pyaudio 
import wave 
import numpy as np 

chunk = 2048 

# open up a wave 
wf = wave.open('test-tones/440hz.wav', 'rb') 
swidth = wf.getsampwidth() 
RATE = wf.getframerate() 
# use a Blackman window 
window = np.blackman(chunk) 
# open stream 
p = pyaudio.PyAudio() 
stream = p.open(format = 
       p.get_format_from_width(wf.getsampwidth()), 
       channels = wf.getnchannels(), 
       rate = RATE, 
       output = True) 

# read some data 
data = wf.readframes(chunk) 
# play stream and find the frequency of each chunk 
while len(data) == chunk*swidth: 
    # write data out to the audio stream 
    stream.write(data) 
    # unpack the data and times by the hamming window 
    indata = np.array(wave.struct.unpack("%dh"%(len(data)/swidth),\ 
             data))*window 
    # Take the fft and square each value 
    fftData=abs(np.fft.rfft(indata))**2 
    # find the maximum 
    which = fftData[1:].argmax() + 1 
    # use quadratic interpolation around the max 
    if which != len(fftData)-1: 
     y0,y1,y2 = np.log(fftData[which-1:which+2:]) 
     x1 = (y2 - y0) * .5/(2 * y1 - y2 - y0) 
     # find the frequency and output it 
     thefreq = (which+x1)*RATE/chunk 
     print "The freq is %f Hz." % (thefreq) 
    else: 
     thefreq = which*RATE/chunk 
     print "The freq is %f Hz." % (thefreq) 
    # read some more data 
    data = wf.readframes(chunk) 
if data: 
    stream.write(data) 
stream.close() 
p.terminate() 
+0

와우 대단한 덕분에, 지금은 어떻게해야 할 것 같습니까? auido 입력에서 오디오를 실시간으로 읽는 방법을 알아 냈습니다. (마이크) – MatijaG

+2

PyAudio 사이트 http://people.csail.mit.edu/hubert/pyaudio/로 이동하여 페이지를 아래로 스크롤하면 마이크에서 입력되는 내용이 표시됩니다. –

+0

uhm을 사용하여 그림을 그릴 수 있습니다. 왜이 오류가 발생합니까 : " " 의 압축을 풀려면 0보다 큰 값이 필요합니다. "y0, y1, y2 = np."fftData [which-1 : which + 2 :])" – MatijaG

0

이전에 파이썬으로 오디오 프로세싱을 시도한 적이 없지만 효율적인 과학/엔지니어링 수치 계산을위한 프레임 워크 인 SciPy (또는 하위 프로젝트 NumPy)을 기반으로 무언가를 만들 수 있습니까? FFT로 시작하여 scipy.fftpack을 볼 수 있습니다.

+1

ok 나는 이것을 찾았습니다. http://www.swharden.com/ 블로그/2010-03-05-real-fft-graph-of-audio-wav-file-or-microphone-input-with 파이썬 -scipy-wckgraph/tho 이제 어떻게 freq 범위를 찾을 수 있을지 궁금합니다. (심지어 SciPy가 약간의 감사를 도왔다. – MatijaG

+0

그래서 이걸하는 법을 알아 냈습니까? –

6

당신은 대신에, 당신은 그래서 당신은 당신이 원하는 바로 주파수를 확인할 수 있습니다 Goertzel algorithm을 개시 아마 더 좋을 것 같아, 인코딩 데이터를 FSK (frequency shift keying)를 사용하려고하는 경우 전체 DFT/FFT.